Kiedy ładuję widok, chciałbym uruchomić kod inicjujący w skojarzonym z nim kontrolerze.
Aby to zrobić, użyłem dyrektywy ng-init w głównym elemencie mojego poglądu:
<div ng-init="init()">
blah
</div>
aw kontrolerze:
$scope.init = function () {
if ($routeParams.Id) {
//get an existing object
});
} else {
//create a new object
}
$scope.isSaving = false;
}
Pierwsze pytanie: czy to właściwy sposób?
Następnie mam problem z kolejnością zachodzących wydarzeń. W widoku mam przycisk „zapisz”, który używa ng-disabled
dyrektywy jako takiej:
<button ng-click="save()" ng-disabled="isClean()">Save</button>
isClean()
funkcja jest określona w sterowniku:
$scope.isClean = function () {
return $scope.hasChanges() && !$scope.isSaving;
}
Jak widać, używa $scope.isSaving
flagi, która została zainicjowana w init()
funkcji.
PROBLEM: gdy widok jest załadowany, funkcja isClean nazywa się przed tym init()
funkcji, stąd flaga isSaving
jest undefined
. Co mogę zrobić, aby temu zapobiec?
Od AngularJS 1.5 powinniśmy używać tego,
$onInit
co jest dostępne w każdym komponencie AngularJS. Zaczerpnięte z dokumentacji cyklu życia komponentów od wersji 1.5 jest to preferowany sposób:var myApp = angular.module('myApp',[]); myApp.controller('MyCtrl', function ($scope) { //default state $scope.name = ''; //all your init controller goodness in here this.$onInit = function () { $scope.name = 'Superhero'; } });
>> Fiddle Demo
Zaawansowany przykład wykorzystania cyklu życia komponentów:
Cykl życia komponentu daje nam możliwość dobrego radzenia sobie z komponentami. Pozwala nam tworzyć zdarzenia np. „Init”, „change” lub „zniszcz” komponent. W ten sposób jesteśmy w stanie zarządzać rzeczami zależnymi od cyklu życia komponentu. Ten mały przykład pokazuje, jak zarejestrować i wyrejestrować
$rootScope
nasłuchiwanie zdarzeń$on
. Wiedząc, że zdarzenie$on
binded na$rootScope
nie będą undinded gdy sterownik traci swoje odniesienie w widoku lub uzyskiwania zniszczone musimy zniszczyć$rootScope.$on
ręcznie słuchacza. Dobrym miejscem na umieszczenie tych rzeczy jest$onDestroy
funkcja cyklu życia komponentu:var myApp = angular.module('myApp',[]); myApp.controller('MyCtrl', function ($scope, $rootScope) { var registerScope = null; this.$onInit = function () { //register rootScope event registerScope = $rootScope.$on('someEvent', function(event) { console.log("fired"); }); } this.$onDestroy = function () { //unregister rootScope event by calling the return function registerScope(); } });
>> Fiddle demo
źródło
Lub możesz po prostu zainicjować inline w kontrolerze. Jeśli używasz funkcji init wewnętrznej kontrolera, nie trzeba jej definiować w zakresie. W rzeczywistości może być wykonywany samodzielnie:
function MyCtrl($scope) { $scope.isSaving = false; (function() { // init if (true) { // $routeParams.Id) { //get an existing object } else { //create a new object } })() $scope.isClean = function () { return $scope.hasChanges() && !$scope.isSaving; } $scope.hasChanges = function() { return false } }
źródło
W swoich projektach używam następującego szablonu:
angular.module("AppName.moduleName", []) /** * @ngdoc controller * @name AppName.moduleName:ControllerNameController * @description Describe what the controller is responsible for. **/ .controller("ControllerNameController", function (dependencies) { /* type */ $scope.modelName = null; /* type */ $scope.modelName.modelProperty1 = null; /* type */ $scope.modelName.modelPropertyX = null; /* type */ var privateVariable1 = null; /* type */ var privateVariableX = null; (function init() { // load data, init scope, etc. })(); $scope.modelName.publicFunction1 = function () /* -> type */ { // ... }; $scope.modelName.publicFunctionX = function () /* -> type */ { // ... }; function privateFunction1() /* -> type */ { // ... } function privateFunctionX() /* -> type */ { // ... } });
źródło