Czy możesz przekazać parametry do kontrolera AngularJS podczas tworzenia?


278

Mam kontrolera odpowiedzialnego za komunikację z interfejsem API w celu zaktualizowania właściwości użytkownika, nazwy, adresu e-mail itp. Każdy użytkownik ma taki, 'id'który jest przekazywany z serwera podczas przeglądania strony profilu.

Chciałbym przekazać tę wartość do kontrolera AngularJS, aby wiedział, jaki jest punkt wejścia API dla bieżącego użytkownika. Próbowałem przekazać wartość ng-controller. Na przykład:

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

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

i w HTML

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

gdzie {% id %}wydrukuj identyfikator wysłany z serwera. ale dostaję błędy.

Jaki jest prawidłowy sposób przekazania wartości do kontrolera podczas jego tworzenia?


6
jeśli masz identyfikator jako część
adresu

Miałem bardzo podobny problem i rozwiązałem go tak, jak napisałem w odpowiedzi. Czasami przy użyciu bibliotek przeoczamy prostą podstawową koncepcję wywołania funkcji JavaScript.
Jigar Patel,

@nickponline Po 21+ nadal uważasz, że to niemożliwe?
om471987,

Odpowiedzi:


362

Uwagi:

Ta odpowiedź jest stara. To tylko dowód koncepcji, w jaki sposób można osiągnąć pożądany rezultat. Jednak może to nie być najlepsze rozwiązanie, jak na niektóre komentarze poniżej. Nie mam żadnej dokumentacji potwierdzającej lub odrzucającej następujące podejście. Zapoznaj się z niektórymi komentarzami poniżej w celu dalszej dyskusji na ten temat.

Oryginalna odpowiedź:

Odpowiedziałem na to tak, absolutnie możesz to zrobić za pomocą ng-initi prostej funkcji init.

Oto przykład tego na plunker

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
Dzięki za to - zaoszczędziłem dużo drapania w głowie, i to idealnie działało w mojej sytuacji. Musiałem zainicjować kontroler za pomocą identyfikatora obiektu, i to było w porządku.
Masonoise 12.04.13

26
Z dokumentów :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
Odpowiedź wyjaśnia, że ​​doktor poleca to podejście, ale czy ktoś może wskazać mi, gdzie doktorzy zapewniają oficjalne rozwiązanie?
Michael Pell,

53
Cóż, myślę, że doktorzy kiepsko zalecają takie podejście bez podania przyczyny. Myślę, że to genialne podejście. Jeśli autorzy frameworka nie chcą, aby frameworka używano w sposób, który jest dla nich „niewłaściwy”, nie powinni umożliwiać korzystania z tego „niewłaściwego” sposobu ... i dostarczać wskazówek dotyczących „ właściwa droga!
Shawn de Wet,

2
słowo ostrzeżenia - jeśli próbujesz powiązać z wartością zakresu lub naprawdę robisz coś, co oczekuje, że wartość będzie obecna w funkcji kontrolera, to już wcześniej uruchomiła funkcję kontrolera ng-init- patrz plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = podgląd
drzaus

143

Spóźniłem się z tym i nie mam pojęcia, czy to dobry pomysł, ale możesz włączyć funkcję $attrswstrzykiwania do funkcji kontrolera, umożliwiając inicjalizację kontrolera za pomocą „argumentów” podanych na elemencie, np.

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>

Znów nie mam pojęcia, czy to dobry pomysł, ale wydaje się, że działa i jest inną alternatywą.


3
Jak miałbym mijać obiekt przy użyciu tego podejścia? var obj = {a: 1, b: 2};
Neil

3
Jest to bardzo rozsądne rozwiązanie problemu tworzenia aplikacji hybrydowej.
superluminarny

2
@ Neil: musisz skreślić swój obiekt Json, a następnie parsować go w kontrolerze. Nie jest to lepsze rozwiązanie, ale może działać. Rozwiązanie Michaela jest odpowiednie dla parametrów podobnych do strun ...
M'sieur Toph '

1
jest to w rzeczywistości bardziej niezawodne niż używanie ng-init- jeśli próbujesz powiązać z wartością zakresu, już wcześniej uruchomiła ona funkcję kontrolera ng-init- patrz plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=preview
drzaus

2
Nie mogę wymyślić całego koła z dyrektywami itp. Jeśli masz kontroler, którego chcesz używać w wielu widokach z kilkoma różnymi parametrami inicjalizacji, jest to najłatwiejsze i najbardziej niezawodne rozwiązanie.
Eric H.

39

To też działa.

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
To dobre rozwiązanie, które działa z istniejącym mechanizmem wstrzykiwania konstruktora. Zasadniczo tworzysz dwie proste usługi o nazwie „nazwa” i „identyfikator”. Wtryskiwacz dba o dopasowanie ich nazwiskami podczas budowy. Patrz: sekcja Przepisów Wartości docs.quarejs.org/guide/providers
Todd

1
Miły. Zauważ, że działa to również z obiektami, a nie tylko pierwotnymi typami, takimi jak łańcuchy.
jbustamovej

Bardziej podoba mi się to rozwiązanie. Byłem w stanie zmodularyzować moje zduplikowane kody poprzez przekazywanie parametrów. Twoje zdrowie!
agentpx

Wygląda to na najbardziej idiomatyczny sposób, ale nie jestem pewien, czy jest to zalecane przez zespół
Angular

Czy to zasadniczo konfiguruje globalne pary klucz / wartość? Czy można je objąć zakresem określonych instancji kontrolera, aby można je było pobrać tylko na kontrolerach podrzędnych w ramach głównego? Jeśli nie, wydaje się, że nie różni się to tak naprawdę od zwykłej globalnej zmiennej Javascript na poziomie okna.
jpierson

16

Widok nie powinien dyktować konfiguracji

W Angular szablon nigdy nie powinien dyktować konfiguracji, która jest z natury tym, czego ludzie pragną, gdy chcą przekazać argumenty do kontrolerów z pliku szablonu. Staje się to śliskie nachylenie. Jeśli ustawienia konfiguracji są zakodowane na stałe w szablonach (np. Za pomocą atrybutu argumentu dyrektywy lub kontrolera), nie można już ponownie użyć tego szablonu do niczego innego niż do pojedynczego użycia. Wkrótce będziesz chciał ponownie użyć tego szablonu, ale z inną konfiguracją, a teraz aby to zrobić, albo będziesz wstępnie przetwarzał szablony, aby wstrzyknąć zmienne, zanim zostaną one przekazane do kątownika, lub używając ogromnych dyrektyw, aby wypluć gigantyczne bloki HTML, dzięki czemu można ponownie użyć całego kodu HTML kontrolera, z wyjątkiem opakowania div i jego argumentów. W przypadku małych projektów to nic wielkiego. W przypadku czegoś dużego (w czym wyróżnia się kąt) robi się brzydko szybko.

Alternatywa: moduły

Ten typ konfiguracji jest przeznaczony do obsługi modułów. W wielu samouczkach kątowych ludzie mają jeden moduł dla całej aplikacji, ale tak naprawdę system jest zaprojektowany i w pełni obsługuje wiele małych modułów, z których każdy otacza małe części całej aplikacji. Najlepiej byłoby, gdyby kontrolery, moduły itp. Były zadeklarowane w osobnych plikach i zszyte w określonych porcjach wielokrotnego użytku. Gdy twoja aplikacja jest zaprojektowana w ten sposób, zyskujesz wiele możliwości ponownego wykorzystania oprócz prostych argumentów kontrolera.

Poniższy przykład ma 2 moduły, ponownie wykorzystujące ten sam kontroler, ale każdy z własnymi ustawieniami konfiguracji. Ustawienia konfiguracji są przekazywane za pomocą wstrzykiwania zależności przy użyciu module.value. Jest to zgodne z kanciastym sposobem, ponieważ mamy następujące elementy: wstrzykiwanie zależności od konstruktora, kod kontrolera wielokrotnego użytku, szablony kontrolera wielokrotnego użytku (kontroler div można łatwo dołączyć do ng-include), system z możliwością testowania jednostkowego bez HTML, a na końcu wielokrotnego użytku moduły jako pojazd do zszywania elementów razem.

Oto przykład:

<!-- 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>

Zobacz to w akcji: jsFiddle .


już głosowałem, ale chcę wyrazić podziękowanie za wasz wkład. ta odpowiedź postawiła mnie na lepszej ścieżce. Stackoverflow jest najlepszy, gdy ludzie dzielą się najlepszymi praktykami, a nie tylko złośliwymi fragmentami. jest to genialne: „szablon nigdy nie powinien dyktować konfiguracji, co z natury jest tym, czego ludzie pragną, gdy chcą przekazać argumenty kontrolerom z pliku szablonu”. dziękuję za wizję laserową w centrum sprawy.
pestofagiczny

15

Jak @akonsu i Nigel Findlater sugerują, można przeczytać url gdzie URL jest index.html#/user/:idze $routeParams.idi używać go wewnątrz sterownika.

Twoja aplikacja:

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

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

usługa zasobów

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

kontroler

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

wtedy elmjest dostępny w widoku w zależności od id.


8

Jeśli ng-initnie służy do przekazywania obiektów $scope, zawsze możesz napisać własną dyrektywę. Oto co mam:

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

JavaScript:

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>

Ale moje podejście może modyfikować tylko obiekty, które są już zdefiniowane w kontrolerze.


Dla porównania działa to świetnie, ale w obecnej wersji kątowej jest to $ attrs (vs attrs)
Dinis Cruz

8

Wygląda na to, że najlepszym rozwiązaniem dla ciebie jest tak naprawdę dyrektywa. Pozwala to nadal mieć kontroler, ale definiować dla niego niestandardowe właściwości.

Użyj tego, jeśli potrzebujesz dostępu do zmiennych w zakresie zawijania:

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>

Użyj tego, jeśli nie potrzebujesz dostępu do zmiennych w zakresie zawijania:

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

Znalazłem przekazywanie zmiennych z $ routeProvider przydatne.

Na przykład używasz jednego kontrolera MyController dla wielu ekranów, przekazując do niego bardzo ważną zmienną „mySuperConstant”.

Użyj tej prostej struktury:

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

Możesz to zrobić podczas konfigurowania tras dla np

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

A później użyj go jako

(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;
  }
})();

Więc tutaj, kiedy konfigurujemy wysłaną trasę: itemType i pobierz ją później z $ routeParams.



3

To pytanie jest stare, ale długo walczyłem, próbując znaleźć odpowiedź na ten problem, który zadziałałby na moje potrzeby i niełatwo go znaleźć. Uważam, że moje następne rozwiązanie jest znacznie lepsze niż obecnie akceptowane, być może dlatego, że angular ma dodatkową funkcjonalność od czasu postawienia tego pytania.

Krótka odpowiedź przy użyciu metody Module.value pozwala przekazać dane do konstruktora kontrolera.

Zobacz mój plunker tutaj

Tworzę obiekt modelu, a następnie kojarzę go ze sterownikiem modułu, odnosząc go do nazwy „model”

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>

Konstruktor w moim kontrolerze akceptuje następnie parametr o tym samym identyfikatorze „model”, do którego może uzyskać dostęp.

Kontroler

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

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

Uwagi:

Korzystam z ręcznej inicjalizacji ładowania początkowego , co pozwala mi zainicjować mój model przed wysłaniem go pod kątem. To działa znacznie ładniej z istniejącym kodem, ponieważ możesz poczekać, aż skonfigurujesz odpowiednie dane i skompilujesz tylko część kątową aplikacji na żądanie, kiedy tylko zechcesz.

W plunkerze dodałem przycisk, aby zaalarmować wartości obiektu modelowego, który początkowo został zdefiniowany w javascript i przekazany do angular, tylko po to, aby potwierdzić, że angular naprawdę odnosi się do obiektu modelowego, zamiast kopiować go i pracować z kopią.

Na tej linii:

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

Przekazuję obiekt MyController do funkcji Module.controller, zamiast deklarować jako funkcję wbudowaną. Myślę, że pozwala nam to na znacznie jaśniejsze zdefiniowanie naszego obiektu kontrolera, ale dokumentacja kątowa ma tendencję do robienia tego bezpośrednio, więc pomyślałem, że należy to wyjaśnić.

Używam składni „kontroler jako” i przypisuję wartości do właściwości „this” MyController, zamiast używać zmiennej „$ scope”. Sądzę, że działałoby to równie dobrze przy użyciu $ scope, przypisanie kontrolera wyglądałoby wtedy tak:

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

a konstruktor kontrolera będzie miał taki podpis:

function MyController ($scope, model) {

Jeśli z jakiegoś powodu chcesz, możesz również dołączyć ten model jako wartość drugiego modułu, który następnie dołączasz jako zależność do modułu podstawowego.

Uważam, że jego rozwiązanie jest znacznie lepsze niż obecnie akceptowane, ponieważ

  1. Model przekazany do kontrolera jest w rzeczywistości obiektem javascript, a nie ciągiem podlegającym ocenie. Jest to prawdziwe odniesienie do obiektu, a zmiany w nim wpływają na inne odwołania do tego obiektu modelu.
  2. Angular mówi, że użycie ng-init przez zaakceptowaną odpowiedź jest niewłaściwym użyciem, czego nie rozwiązuje to rozwiązanie.

Sposób, w jaki Angular wydaje się działać w większości innych przykładów, które widziałem, ma kontroler definiujący dane modelu, co nigdy nie miało dla mnie sensu, nie ma oddzielenia między modelem a kontrolerem, co tak naprawdę nie wydaje się MVC do mnie. To rozwiązanie pozwala naprawdę mieć całkowicie oddzielny obiekt modelu, który przekazujesz do kontrolera. Warto również zauważyć, że jeśli zastosujesz dyrektywę ng-include, możesz umieścić cały kątowy HTML w osobnym pliku, całkowicie oddzielając widok modelu i kontroler na osobne moduły.


2

Jeśli używasz routera kątowego, to jest właściwe rozwiązanie: https://github.com/angular-ui/ui-router/wiki#resolve

Zasadniczo deklarujesz zestaw zależności do „rozwiązania” przed utworzeniem instancji kontrolera. Możesz zadeklarować zależności dla każdego ze swoich „stanów”. Te zależności są następnie przekazywane do „konstruktora” kontrolera.


1

Jednym ze sposobów osiągnięcia tego byłoby posiadanie oddzielnej usługi, która mogłaby być wykorzystana jako „naczynie” dla argumentów, w których są członkami danych publicznych.


Najlepsza odpowiedź, IMO. Obecnie w niektórych przypadkach używam również pamięci przeglądarki dla tych użytkowników, którzy odważą się nacisnąć F5, więc ten stan został utrzymany.
Dormouse

1

Nie podobało mi się żadne z rozwiązań tutaj dla mojego konkretnego przypadku użycia, więc pomyślałem, że opublikuję to, co zrobiłem, ponieważ nie widziałem tego tutaj.

Chciałem po prostu użyć kontrolera bardziej jak dyrektywy, w pętli powtarzania ng:

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

Teraz, aby uzyskać dostęp do objParametertworzenia w ramach każdego DirectorLikeController (lub aby uzyskać aktualny obiekt objParameter W DOWOLNYM czasie), wszystko co muszę zrobić, to wstrzyknąć $ scope i wywołać $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); 
});

Jedynym prawdziwym minusem, jaki widzę, jest to, że wymaga, aby kontroler nadrzędny wiedział, że parametr ma nazwę objParameter.


0

Nie, nie jest to możliwe. Myślę, że możesz użyć ng-init jako hack http://docs.angularjs.org/api/ng.directive:ngInit .


4
Zaczynam się różnić, ale możesz to zrobić za pomocą ng-init i za pomocą funkcji inicjacji.
Jigar Patel,

słowo ostrzeżenia - jeśli próbujesz powiązać z wartością zakresu lub naprawdę robisz coś, co oczekuje, że wartość będzie obecna w funkcji kontrolera, to już wcześniej uruchomiła funkcję kontrolera ng-init- patrz plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = podgląd
drzaus

Tak to mozliwe. Przynajmniej użyłbyś parametrów danych lub cokolwiek innego. Ale to zdecydowanie możliwe.
Juan

0

Oto rozwiązanie (oparte na sugestii Marcina Wyszyńskiego), które działa tam, gdzie chcesz przekazać wartość do kontrolera, ale nie jawnie deklarujesz kontrolera w html (który wydaje się wymagać tego ng-init) - jeśli na przykład renderujesz swoje szablony z podglądem ng i deklarujesz każdy kontroler dla odpowiedniej trasy przez routeProvider.

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>

W tym rozwiązaniu CurrentUser jest usługą, którą można wstrzyknąć do dowolnego kontrolera, z dostępną wówczas właściwością .name.

Dwie notatki:

  • Problemem, który napotkałem, jest to, że .name jest ustawiane po załadowaniu kontrolera, więc jako obejście mam krótki limit czasu przed renderowaniem nazwy użytkownika w zakresie kontrolera. Czy istnieje fajny sposób czekania, aż usługa .name zostanie ustawiona w serwisie?

  • wydaje się to bardzo łatwym sposobem na włączenie bieżącego użytkownika do aplikacji Angular przy całym uwierzytelnieniu poza Angular. Możesz mieć filtr before_filter, aby uniemożliwić niezalogowanym użytkownikom dostęp do html, w którym ładowana jest aplikacja Angular, aw tym html możesz po prostu interpolować nazwę zalogowanego użytkownika, a nawet jego identyfikator, jeśli chcesz wejść w interakcję z danymi użytkownika za pośrednictwem żądań http z aplikacji Angular. Można zezwolić niezalogowanym użytkownikom na korzystanie z aplikacji Angular z domyślnym „gościem”. Wszelkie porady dotyczące tego, dlaczego takie podejście byłoby złe, byłyby mile widziane - zbyt łatwo jest być rozsądnym!)


0

Jest to rozwinięcie doskonałej odpowiedzi @ Michaela Tillera . Jego odpowiedź działa na inicjalizację zmiennych z widoku poprzez wstrzyknięcie $attrsobiektu do kontrolera. Problem występuje, jeśli ten sam kontroler jest wywoływany $routeProviderpodczas nawigacji przez routing. Następnie pojawia się błąd wtryskiwacza, Unknown provider : $attrsProviderponieważ $attrsjest on dostępny do wstrzyknięcia tylko podczas kompilacji widoku. Rozwiązaniem jest przepuszczenie zmiennej (foo) $routeParamspodczas inicjowania kontrolera z trasy i $attrspodczas inicjowania kontrolera z widoku. Oto moje rozwiązanie.

Z trasy

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

To obsługuje adres URL taki jak '/mypage/bar'. Jak widać, foo jest przekazywany przez url param, a my udostępniamy $injectorpusty obiekt, $attrsaby nie występowały błędy wtryskiwaczy.

Z widoku

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

</div>

Teraz kontroler

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'

});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.