Parametreleri oluşturma sırasında bir AngularJS denetleyicisine aktarabilir misiniz?


278

Bir kullanıcı, ad, e-posta, vb. Özelliklerini güncellemek için bir API ile iletişim kurmaktan sorumlu bir denetleyicim var. Her kullanıcının 'id'profil sayfası görüntülendiğinde sunucudan geçirilen bir var.

Geçerli kullanıcı için API giriş noktasının ne olduğunu bilmesi için bu değeri AngularJS denetleyicisine iletmek istiyorum. Değeri içeri aktarmayı denedim ng-controller. Örneğin:

function UserCtrl(id, $scope, $filter) {

$scope.connection = $resource('api.com/user/' + id)

ve HTML'de

<body ng-controller="UserCtrl({% id %})">

nerede {% id %}sunucusundan gönderilen id yazdırın. ama hatalar alıyorum.

Bir değeri yaratıldığında bir denetleyiciye aktarmanın doğru yolu nedir?



Çok benzer bir sorunum vardı ve cevabımda yayınladığım gibi çözdüm. Bazen kütüphaneleri kullanarak JavaScript işlev çağrısının basit temel kavramını göz ardı ederiz.
Jigar Patel

@nickponline 21 yaşından sonra hala bunun mümkün olmadığını mı düşünüyorsunuz?
om471987

Yanıtlar:


362

Notlar:

Bu cevap eski. Bu sadece istenen sonucun nasıl elde edilebileceğine dair bir kavram kanıtıdır. Bununla birlikte, aşağıdaki bazı yorumlara göre en iyi çözüm olmayabilir. Aşağıdaki yaklaşımı destekleyecek veya reddedecek herhangi bir belgem yok. Bu konuyla ilgili daha fazla tartışma için lütfen aşağıdaki yorumlardan bazılarına bakın.

Orijinal Yanıt:

Bunu evet olarak yanıtladım ng-initve bunu kullanarak basit bir başlangıç ​​işlevini kesinlikle yapabilirsiniz .

İşte dalgıç üzerinde bir örnek

HTML

<!DOCTYPE html>
<html ng-app="angularjs-starter">
  <head lang="en">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
  </head>  
  <body ng-controller="MainCtrl" ng-init="init('James Bond','007')">
    <h1>I am  {{name}} {{id}}</h1>
  </body>
</html>

JavaScript

var app = angular.module('angularjs-starter', []);

app.controller('MainCtrl', function($scope) {

  $scope.init = function(name, id)
  {
    //This function is sort of private constructor for controller
    $scope.id = id;
    $scope.name = name; 
    //Based on passed argument you can make a call to resource
    //and initialize more objects
    //$resource.getMeBond(007)
  };


});

5
Bunun için teşekkürler - bana çok fazla kafa çizik kurtardı ve durumum için mükemmel çalıştı. Denetleyicimi bir nesne kimliğiyle başlatmak zorunda kaldım ve bu doğru.
Masonoise

26
Dokümanlar'dan :The only appropriate use of ngInit for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
Sergey Goliney

8
Cevap, doktorun bu yaklaşıma karşı tavsiyede bulunduğunu açıkça ortaya koyuyor, ancak birisi bana dokümanların resmi çözümü sağladığı yere işaret edebilir mi?
Michael Pell

53
Bence bu nedenlere neden olmadan bu yaklaşıma karşı tavsiyede bulunan dokümanlar zayıf. Bence bu harika bir yaklaşım. Eğer çerçeve yazarları çerçevenin kendilerine "yanlış" bir şekilde kullanılmasını istemiyorlarsa, o zaman "yanlış" şekilde kullanılmasını mümkün kılmamalı ve " doğru yol!
Shawn de Wet

2
bir uyarı kelimesi - bir kapsam değerine bağlanmaya çalışıyorsanız veya gerçekten değer kontrolör işlevinde olması beklenen herhangi bir şey yapıyorsanız, ng-initgerçekleşmeden önce zaten kontrolör işlevini çalıştırır - bkz. plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = önizleme
drzaus

143

Çok geç Buna değilim ve bunun iyi bir fikir olup olmadığını hiçbir fikrim yok, ama sen içerebilir $attrsdenetleyici bir unsuru, sağlanan "argümanları" kullanarak başlatıldığını sağlayan kontrolör fonksiyonunda enjektabl örn

app.controller('modelController', function($scope, $attrs) {
    if (!$attrs.model) throw new Error("No model for modelController");

    // Initialize $scope using the value of the model attribute, e.g.,
    $scope.url = "http://example.com/fetch?model="+$attrs.model;
})

<div ng-controller="modelController" model="foobar">
  <a href="{{url}}">Click here</a>
</div>

Yine, bunun iyi bir fikir olup olmadığı hakkında hiçbir fikrim yok, ama işe yarıyor gibi görünüyor ve başka bir alternatif.


3
Bu yaklaşımı kullanarak bir nesneyi nasıl iletirim? var obj = {a: 1, b: 2};
Neil

3
Bu, hibrit bir uygulama üretme sorununa çok makul bir çözümdür.
superluminary

2
@Neil: json nesnenizi dizginlemeniz ve ardından denetleyicinin içinde ayrıştırmanız gerekir. Güzel bir çözüm değil, ama işe yarayabilir. Michael'ın çözümü dize benzeri parametreler için iyi ...
Mieur Toph '

1
bu aslında kullanmaktan daha güvenilirdir ng-init- bir kapsam değerine bağlanmaya çalışıyorsanız, ng-initgerçekleşmeden önce kontrolör işlevini zaten çalıştırır - bkz. plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=preview
drzaus

2
Direksiyon vb. İle tekerleği yeniden icat edemiyorum. Birkaç farklı başlatma parametresi ile birden fazla görünümde kullanmak istediğiniz bir denetleyiciniz varsa, bu en kolay ve en güvenilir çözümdür.
Eric H.

39

Bu da işe yarıyor.

JavaScript:

var app = angular.module('angularApp', []);

app.controller('MainCtrl', function($scope, name, id) {
    $scope.id = id;
    $scope.name = name;
    // and more init
});

Html:

<!DOCTYPE html>
<html ng-app="angularApp">
  <head lang="en">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
    <script>
       app.value("name", "James").value("id", "007");
    </script>
  </head>
  <body ng-controller="MainCtrl">
    <h1>I am  {{name}} {{id}}</h1>
  </body>
</html>

3
Bu, mevcut yapıcı enjeksiyon mekanizması ile çalışan iyi bir çözümdür. Özünde, 'isim' ve 'kimlik' olarak adlandırılan iki basit hizmet oluşturuyorsunuz. Enjektör, inşaat sırasında bunları adlarıyla eşleştirmeye özen gösterir. Bkz: docs.angularjs.org/guide/providers
Todd

1
Güzel. Bunun yalnızca dizeler gibi ilkel türlerle değil, nesnelerle de çalıştığını unutmayın.
jbustamovej

Bu çözümü daha çok seviyorum. Parametre geçişi ile yinelenen kodlarımı modüle edebildim. Şerefe!
agentpx

Bu en deyimsel yol gibi görünüyor, ancak açısal ekip tarafından önerildiğinden emin değilim
VinGarcia

Bu temelde küresel anahtar / değer çiftleri mi kuruyor? Bunlar belirli bir kontrolör örneklerine dahil edilebilir, böylece yalnızca ana kontrol altındaki çocuk kontrolörlerinden alınır? Değilse, bu sadece pencere düzeyinde normal bir global Javascript değişkeni ayarlamaktan çok farklı değil gibi görünüyor.
jpierson

16

Görünüm yapılandırmayı dikte etmemelidir

Açısal'da, şablon hiçbir zaman yapılandırmayı dikte etmemelidir; bu, insanların bir şablon dosyasından denetleyicilere argümanlar iletmek istediklerinde doğası gereği istediği şeydir. Bu kaygan bir eğim haline gelir. Yapılandırma ayarları şablonlarda sabit olarak kodlanmışsa (örneğin, bir yönerge veya denetleyici bağımsız değişkeni özniteliği gibi), artık bu şablonu tek kullanımdan başka bir şey için yeniden kullanamazsınız. Yakında bu şablonu yeniden kullanmak isteyeceksiniz, ancak şimdi farklı yapılandırmayla ve şimdi bunu yapmak için, değişkenleri açısal hale gelmeden önce enjekte etmek için şablonları önceden işleyeceksiniz veya dev tükürmek için büyük direktifler kullanacaksınız. HTML blokları sayesinde sarıcı div ve argümanları dışında tüm denetleyici HTML'sini yeniden kullanırsınız. Küçük projeler için önemli değil. Büyük bir şey için (açısal mükemmel olan) çirkin hızlı olur.

Alternatif: Modüller

Bu tip yapılandırma, modüllerin işleyeceği şekilde tasarlanmıştır. Birçok açısal öğreticide, insanların tüm uygulamaları için tek bir modül vardır, ancak gerçekten sistem tasarlanmıştır ve her biri toplam uygulamanın küçük parçalarını saran birçok küçük modülü tamamen destekler. İdeal olarak, kontrolörler, modüller vb. Ayrı dosyalarda bildirilecek ve yeniden kullanılabilir belirli parçalar halinde birleştirilecektir. Uygulamanız bu şekilde tasarlandığında, kolay denetleyici argümanlarına ek olarak çok fazla yeniden kullanım elde edersiniz.

Aşağıdaki örnekte, aynı denetleyiciyi kullanan ancak her birinin kendi yapılandırma ayarları olan 2 modül vardır. Bu yapılandırma ayarları, bağımlılık enjeksiyonu kullanılarak aktarılır module.value. Aşağıdakilere sahip olduğumuz için bu açısal şekilde yapışır: yapıcı bağımlılığı enjeksiyonu, yeniden kullanılabilir denetleyici kodu, yeniden kullanılabilir denetleyici şablonları (denetleyici div, ng-include ile kolayca dahil edilebilir), HTML olmadan kolayca birim test edilebilir sistem ve son olarak yeniden kullanılabilir parçaları birleştirmek için araç olarak modüller.

İşte bir örnek:

<!-- index.html -->
<div id="module1">
    <div ng-controller="MyCtrl">
        <div>{{foo}}</div>
    </div>
</div>
<div id="module2">
    <div ng-controller="MyCtrl">
        <div>{{foo}}</div>
    </div>
</div>
<script>
    // part of this template, or a JS file designed to be used with this template
    angular.element(document).ready(function() {
        angular.bootstrap(document.getElementById("module1"), ["module1"]);
        angular.bootstrap(document.getElementById("module2"), ["module2"]);
    });
</script>

<!-- scripts which will likely in be in their seperate files -->
<script>
    // MyCtrl.js
    var MyCtrl = function($scope, foo) {
    $scope.foo = foo;
    }

    MyCtrl.$inject = ["$scope", "foo"];

    // Module1.js
    var module1 = angular.module('module1', []);
    module1.value("foo", "fooValue1");
    module1.controller("MyCtrl", MyCtrl);

    // Module2.js file
    var module2 = angular.module('module2', []);
    module2.value("foo", "fooValue2");
    module2.controller("MyCtrl", MyCtrl);
</script>

Uygulamaya bakın: jsFiddle .


Ben zaten iptal ettim, ama katkınız için teşekkür ederim. bu cevap beni daha iyi bir yola soktu. stackoverflow en iyisi, insanlar sadece hileli snippet'leri değil, en iyi uygulamaları paylaştıklarında en iyisidir. bu mükemmel: "şablon asla yapılandırmayı dikte etmemelidir, bu da insanların bir şablon dosyasındaki denetleyicilere argümanlar iletmek istediklerinde doğası gereği istediği şeydir". konunun kalbine lazer vizyonu yaptığınız için teşekkür ederiz.
pestophagous

15

@Akonsu ve Nigel Findlater önermek gibi, url'dir url okuyabilir index.html#/user/:idile $routeParams.idve denetleyici içinde kullanın.

uygulamanız:

var app = angular.module('myApp', [ 'ngResource' ]);

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/:type/:id', {templateUrl: 'myView.html', controller: 'myCtrl'});
}]);

kaynak servisi

app.factory('MyElements', ['$resource', function($resource) {
     return $resource('url/to/json/:type/:id', { type:'@type', id:'@id' });
}]);

kontrol eden, denetleyici

app.controller('MyCtrl', ['$scope', '$routeParams', 'MyElements', function($scope, $routeParams, MyElements) {
    MyElements.get({'type': $routeParams.type, "id": $routeParams.id }, function(elm) {
        $scope.elm = elm;
    })
}]);

sonra, elmgörünümüne bağlı olarak erişilebilir id.


8

ng-initNesnelerin içeri aktarılması için değilse , $scopeher zaman kendi direktifinizi yazabilirsiniz. İşte sahip olduğum şey:

http://jsfiddle.net/goliney/89bLj/

Javasript:

var app = angular.module('myApp', []);
app.directive('initData', function($parse) {
    return function(scope, element, attrs) {
        //modify scope
        var model = $parse(attrs.initData);
        model(scope);
    };
});

function Ctrl1($scope) {
    //should be defined
    $scope.inputdata = {foo:"east", bar:"west"};
}

Html:

<div ng-controller="Ctrl1">
    <div init-data="inputdata.foo=123; inputdata.bar=321"></div>
</div>

Ancak yaklaşımım yalnızca denetleyicide zaten tanımlanan nesneleri değiştirebilir.


Referans için bu harika çalışıyor ama açısal mevcut sürümünde $ attrs (vs attrs)
Dinis Cruz

8

Görünüşe göre sizin için en iyi çözüm aslında bir direktif. Bu, kontrol cihazınıza sahip olmanıza izin verir, ancak bunun için özel özellikler tanımlar.

Kaydırma kapsamındaki değişkenlere erişmeniz gerekiyorsa bunu kullanın:

angular.module('myModule').directive('user', function ($filter) {
  return {
    link: function (scope, element, attrs) {
      $scope.connection = $resource('api.com/user/' + attrs.userId);
    }
  };
});

<user user-id="{% id %}"></user>

Kaydırma kapsamındaki değişkenlere erişmeniz gerekmiyorsa bunu kullanın:

angular.module('myModule').directive('user', function ($filter) {
  return {
    scope: {
      userId: '@'
    },
    link: function (scope, element, attrs) {
      $scope.connection = $resource('api.com/user/' + scope.userId);
    }
  };
});

<user user-id="{% id %}"></user>

7

$ RouteProvider usefull değişkenleri buldum.

Örneğin, birden çok ekran için bir denetleyici MyController kullanıyorsunuz ve içinde çok önemli bir değişken olan "mySuperConstant" ı geçiyorsunuz.

Bu basit yapıyı kullanın:

Router:

$routeProvider
            .when('/this-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "123"
            })
            .when('/that-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "456"
            })
            .when('/another-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "789"
            })

MyController:

    MyController: function ($scope, $route) {
        var mySuperConstant: $route.current.mySuperConstant;
        alert(mySuperConstant);

    }

6

Örneğin, rotaları ayarlarken yapabilirsiniz.

 .when('/newitem/:itemType', {
            templateUrl: 'scripts/components/items/newEditItem.html',
            controller: 'NewEditItemController as vm',
            resolve: {
              isEditMode: function () {
                return true;
              }
            },
        })

Ve daha sonra

(function () {
  'use strict';

  angular
    .module('myApp')
    .controller('NewEditItemController', NewEditItemController);

  NewEditItemController.$inject = ['$http','isEditMode',$routeParams,];

  function NewEditItemController($http, isEditMode, $routeParams) {
    /* jshint validthis:true */

    var vm = this;
    vm.isEditMode = isEditMode;
    vm.itemType = $routeParams.itemType;
  }
})();

Burada, gönderdiğimiz rotayı ayarladığımızda: itemType ve daha sonra $ routeParams'tan yeniden deneyin.



3

Bu soru eski ama ihtiyaçlarım için işe yarayacak ve kolayca bulamayan bu soruna cevap vermeye çalışırken uzun süre mücadele ettim. Aşağıdaki çözümümün şu anda kabul edilen çözümden çok daha iyi olduğuna inanıyorum, çünkü belki de bu soru başlangıçta olduğu için açısal işlevsellik ekledi.

Module.value yöntemini kullanarak kısa yanıt, verileri bir denetleyici yapıcısına geçirmenizi sağlar.

Dalma makinemi burada gör

Bir model nesnesi oluşturuyorum, sonra onu modülün denetleyicisi ile ilişkilendiriyorum, 'model' adıyla referans alıyorum

HTML / JS

  <html>
  <head>
    <script>
      var model = {"id": 1, "name":"foo"};

      $(document).ready(function(){
        var module = angular.module('myApp', []);
        module.value('model', model);
        module.controller('MyController', ['model', MyController]);
        angular.bootstrap(document, ['myApp']);
      });

      function confirmModelEdited() {
        alert("model name: " + model.name + "\nmodel id: " + model.id);
      }
    </script>

  </head>
  <body >
      <div ng-controller="MyController as controller">
        id: {{controller.model.id}} <br>
        name: <input ng-model="controller.model.name"/>{{controller.model.name}}
        <br><button ng-click="controller.incrementId()">increment ID</button>
        <br><button onclick="confirmModelEdited()">confirm model was edited</button>
    </div>
  </body>

</html>

Denetleyicimdeki kurucu, daha sonra erişebileceği aynı tanımlayıcı 'model' ile bir parametreyi kabul eder.

kontrolör

function MyController (model) {
  this.model = model;
}

MyController.prototype.incrementId = function() {
  this.model.id = this.model.id + 1;
}

Notlar:

Açılıma göndermeden önce modelimi başlatmamı sağlayan bootstrapping'in manuel olarak başlatılmasını kullanıyorum . İlgili verilerinizi ayarlamak ve yalnızca istediğiniz zaman uygulamanızın açısal alt kümesini derlemek için bekleyebileceğinizden, bu mevcut kodla çok daha güzel oynar.

Dalma makinesinde, başlangıçta javascript'te tanımlanan ve açısal olarak geçen model nesnesinin değerlerini uyarmak için bir düğme ekledim, sadece açısalın kopyalamak ve bir kopya ile çalışmak yerine model nesnesine gerçekten başvurduğunu doğrulamak için.

Bu hatta:

module.controller('MyController', ['model', MyController]);

MyController nesnesini Module.controller işlevine geçerek yerine satır içi işlev olarak bildiriyorum. Bu bizim denetleyici nesnemizi çok daha net bir şekilde tanımlamamıza izin verdiğini düşünüyorum, ancak Açısal belgeler bunu satır içi yapmaya eğilimlidir, bu yüzden açıklık taşıdığını düşündüm.

"Denetleyici olarak" sözdizimi kullanarak ve "$ scope" değişkeni yerine, MyController "bu" özelliğine değerler atama. Ben de $ kapsamı kullanarak iyi çalışır inanıyorum, denetleyici atama sonra böyle bir şey olurdu:

module.controller('MyController', ['$scope', 'model', MyController]);

ve denetleyici kurucusunun şöyle bir imzası olurdu:

function MyController ($scope, model) {

İstediğiniz herhangi bir nedenle, bu modeli ikinci bir modülün değeri olarak, daha sonra birincil modülünüze bağımlı olarak iliştirebilirsiniz.

Çözümünün şu anda kabul edilenden çok daha iyi olduğuna inanıyorum çünkü

  1. Denetleyiciye aktarılan model aslında değerlendirilen bir dize değil, bir javascript nesnesidir. Nesneye gerçek bir referanstır ve nesnede yapılan değişiklikler bu model nesnesine yapılan diğer referansları etkiler.
  2. Angular, kabul edilen cevabın ng-init kullanımının bu çözümün yapmadığı bir yanlış kullanım olduğunu söylüyor.

Angular'ın gördüğüm diğer örneklerin çoğunda nasıl çalıştığı, modelin verilerini tanımlayan, bana hiç mantıklı gelmeyen denetleyiciye sahip, model ve denetleyici arasında hiçbir ayrım görünmüyor. MVC bana. Bu çözüm, denetleyiciye ilettiğiniz tamamen ayrı bir model nesnesine sahip olmanızı sağlar. Ayrıca, ng-include direktifini kullanırsanız, tüm açısal html'nizi ayrı bir dosyaya koyabilir, model görünümünüzü ve denetleyicinizi ayrı modüler parçalara tamamen ayırabilirsiniz.


2

Açısal UI yönlendirici kullanıyorsanız, bu doğru çözümdür: https://github.com/angular-ui/ui-router/wiki#resolve

Temel olarak, denetleyici başlatılmadan önce bir dizi bağımlılığın "çözümleneceğini" bildirirsiniz. "Eyaletlerinizin" her biri için bağımlılık bildirebilirsiniz. Bu bağımlılıklar daha sonra kontrolörün "yapıcısına" aktarılır.


1

Bunu yapmanın bir yolu, halka açık veri üyesi oldukları argümanlar için 'gemi' olarak kullanılabilecek ayrı bir hizmete sahip olmaktır.


En iyi cevap, IMO. Şu anda bazı durumlarda F5'i vurmaya cesaret eden kullanıcılar için tarayıcı depolamasını da kullanıyorum, bu nedenle bu durum korunuyor.
Dormouse

1

Özel kullanım durumum için buradaki çözümlerden hiçbirini gerçekten beğenmedim, bu yüzden burada ne yaptığımı göndereceğimi düşündüm çünkü burada görmedim.

Ben sadece bir ng-tekrar döngü içinde bir kontrolör daha bir direktif gibi kullanmak istedim:

<div ng-repeat="objParameter in [{id:'a'},{id:'b'},{id:'c'}]">
  <div ng-controller="DirectiveLikeController as ctrl"></div>
</div>

Şimdi, objParameterher DirectiveLikeController içindeki yaratıma erişmek (veya HERHANGİ bir zamanda güncel objParameter'ı almak) için tek yapmam gereken $ scope ve call'ı enjekte etmek $scope.$eval('objParameter'):

var app = angular.module('myapp', []);
app.controller('DirectiveLikeController',['$scope'], function($scope) {
   //print 'a' for the 1st instance, 'b' for the 2nd instance, and 'c' for the 3rd.
   console.log($scope.$eval('objParameter').id); 
});

Gördüğüm tek gerçek dezavantajı, parametrenin adlandırıldığını bilmek için ana denetleyiciye ihtiyaç duymasıdır objParameter.


0

Hayır, bu mümkün değil. Bence ng-init'i hack olarak kullanabilirsiniz http://docs.angularjs.org/api/ng.directive:ngInit .


4
Farklı olmaya yalvarıyorum ama bunu ng-init kullanarak ve bir init işlevi kullanarak yapabilirsiniz.
Jigar Patel

bir uyarı kelimesi - bir kapsam değerine bağlanmaya çalışıyorsanız veya gerçekten kontrolörün fonksiyonunda mevcut olmasını bekleyen herhangi bir şey yapıyorsanız, ng-initgerçekleşmeden önce kontrolör fonksiyonunu zaten çalıştırır - bkz. plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = önizleme
drzaus

Evet mümkün. En azından veri parametrelerini veya her neyse kullanabilirsiniz. Ama bu kesinlikle mümkün.
Juan

0

Denetleyicinize bir değer aktarmak istediğiniz yerde çalışan ancak denetleyiciyi html'nizde (hangi ng-init gerektiriyor gibi görünüyor) açıkça belirtmediğiniz bir yerde çalışan (Marcin Wyszynski'nin önerisine dayanarak) bir çözüm var. Şablonlarınızı ng-view ile oluşturuyorsunuz ve routeProvider aracılığıyla ilgili rota için her denetleyiciyi bildiriyorsunuz.

JS

messageboard.directive('currentuser', ['CurrentUser', function(CurrentUser) {
  return function(scope, element, attrs) {
    CurrentUser.name = attrs.name;
  };
}]);

html

<div ng-app="app">
  <div class="view-container">
    <div ng-view currentuser name="testusername" class="view-frame animate-view"></div>
  </div>
</div>

Bu çözümde, CurrentUser herhangi bir denetleyiciye enjekte edilebilen bir hizmettir ve .name özelliği kullanılabilir durumdadır.

İki not:

  • karşılaştığım bir sorun, denetleyicinin yüklendikten sonra .name ayarlanmasıdır, bu nedenle bir geçici çözüm olarak denetleyicinin kapsamında kullanıcı adı oluşturmadan önce kısa bir zaman aşımı var. Hizmette .name ayarlanana kadar beklemenin düzgün bir yolu var mı?

  • Bu, Angular dışında geçerli bir kullanıcıyı Angular Uygulamanıza almanın çok kolay bir yolu gibi geliyor. Oturum açmamış kullanıcıların Açısal uygulamanızın önyüklendiği html'ye erişmesini önlemek için bir before_filter'e sahip olabilirsiniz ve bu html içinde, kullanıcının ayrıntılarıyla etkileşim kurmak istiyorsanız, oturum açmış kullanıcının adını ve hatta kimliğini enterpolasyon yapabilirsiniz. Açısal uygulamanızdan http istekleri yoluyla. Giriş yapmayan kullanıcıların Açısal Uygulamayı varsayılan 'misafir kullanıcı' ile kullanmasına izin verebilirsiniz. Bu yaklaşımın neden kötü olacağına dair herhangi bir tavsiye memnuniyetle karşılanacaktır - mantıklı olmak çok kolay!)


0

@Michael Tiller'ın mükemmel cevabının bir uzantısı . Cevabı, $attrsnesneyi denetleyiciye enjekte ederek değişkenleri görünümden başlatmak için çalışır . $routeProviderYönlendirme ile gezinirken aynı denetleyici çağrılırsa sorun oluşur . Daha sonra enjektör hatası alıyorsunuz Unknown provider : $attrsProviderçünkü $attrssadece görünüm derlendiğinde enjeksiyon için kullanılabilir. Çözüm, $routeParamsdenetleyiciyi rotadan $attrsbaşlatırken ve denetleyiciyi görünümden başlatırken değişkeni (foo) geçirmektir . İşte benim çözümüm.

Rotadan

$routeProvider.
        when('/mypage/:foo', {
            templateUrl: 'templates/mypage.html',
            controller: 'MyPageController',
            caseInsensitiveMatch: true,
            resolve: {
                $attrs: function () {
                    return {};
                }
            }
        });

Bu, gibi bir URL'yi işler '/mypage/bar'. Gördüğünüz gibi foo url param tarafından geçti ve enjektör hataları $injectoriçin boş bir nesne sağlıyoruz $attrs.

Görünümden

<div ng-controller="MyPageController" data-foo="bar">

</div>

Şimdi kontrolör

var app = angular.module('myapp', []);
app.controller('MyPageController',['$scope', '$attrs', '$routeParams'], function($scope, $attrs, $routeParams) {
   //now you can initialize foo. If $attrs contains foo, it's been initialized from view
   //else find it from $routeParams
   var foo = $attrs.foo? $attrs.foo : $routeParams.foo;
   console.log(foo); //prints 'bar'

});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.