Quando carrego uma vista, I'gostaria de executar algum código de inicialização no seu controlador associado.
Para o fazer, I'usei a directiva ng-init sobre o elemento principal do meu ponto de vista:
<div ng-init="init()">
blah
</div>
e no controlador:
$scope.init = function () {
if ($routeParams.Id) {
//get an existing object
});
} else {
//create a new object
}
$scope.isSaving = false;
}
Primeira questão: é esta a forma correcta de o fazer?
A seguir, tenho um problema com a sequência dos acontecimentos que estão a ter lugar. Na perspectiva, tenho um ' save' botão, que utiliza a directiva "não-inválido" como tal:
<button ng-click="save()" ng-disabled="isClean()">Save</button>
a função isClean()
é definida no controlador:
$scope.isClean = function () {
return $scope.hasChanges() && !$scope.isSaving;
}
Como se pode ver, utiliza a bandeira $scope.isSaving', que foi inicializada na função
init()`.
PROBLEMA: quando a vista é carregada, a função isClean chama-se antes a função init()
, daí que a bandeira saving
seja undefined
. O que posso fazer para evitar isso?
Quando a sua visão carrega, o seu controlador associado também carrega. Em vez de utilizar ng-init
, basta chamar o seu método init()
no seu controlador:
$scope.init = function () {
if ($routeParams.Id) {
//get an existing object
} else {
//create a new object
}
$scope.isSaving = false;
}
...
$scope.init();
Uma vez que o seu controlador funciona antes da "ing-init", isto também resolve o seu segundo problema.
[violino][1][1]
Como "John David Five" mencionou, talvez não queira anexar isto a "$$scope" de modo a tornar este método privado.
var init = function () {
// do something
}
...
init();
[Ver jsFiddle][2] [Ver jsFiddle][3]
Se quiser esperar que certos dados sejam pré-definidos, ou mover esse pedido de dados para uma resolução ou adicionar um observador a essa colecção ou objecto e chamar o seu método de init quando os seus dados satisfizerem os seus critérios de init. Normalmente retiro o observador uma vez preenchidos os meus requisitos de dados, para que a função init não volte a funcionar aleatoriamente se os dados que o seu observador observar mudarem e satisfizerem os seus critérios para executar o seu método init.
var init = function () {
// do something
}
...
var unwatch = scope.$watch('myCollecitonOrObject', function(newVal, oldVal){
if( newVal && newVal.length > 0) {
unwatch();
init();
}
});
Ou pode simplesmente inicializar em linha no controlador. Se utilizar uma função init interna ao controlador, esta não't precisa de ser definida no âmbito. Na verdade, pode ser autoexecutada:
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 }
}
Utilizo o seguinte modelo nos meus projectos:
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 */ {
// ...
}
});