Direttive Isolato Scope non funziona correttamente insieme alle viste nidificate?(AngularJS / UI Router)
Domanda
Sto usando l'ui-router in un progetto AngularJS in cui ho una vista annidata che contiene una direttiva personalizzata. Questa direttiva rende un campo di input (consente di dire un campo filtro) e il suo valore dovrebbe essere sincronizzato con l'ambito del controller.
.
funziona bene per questa direttiva, quando la vista / stato non è nidificato:
jsfiddle / non nidificato / funzionante come previsto
var myApp = angular.module('myApp', ['ui.router', 'myComponents'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.
state('home', {
url: '',
template: '<my-filter text-filter="theFilter"></my-filter><button ng-click="inspect()">inspect</button>{{ theFilter |json}}',
controller: 'myController'
});
}]);
var components = angular.module('myComponents', []);
components.directive('myFilter', [function () {
return {
restrict: 'E',
template: '<input type="text" name="filter" ng-model="textFilter">',
scope: {
textFilter: '='
}
};
}]);
components.controller('myController', ['$scope', function ($scope) {
$scope.theFilter = 'initial filter';
$scope.inspect = function () {
alert($scope.theFilter);
}
}]);
.
Vista:
<div ng-app="myApp">
<div ui-View></div>
</div>
.
Quando modifico il testo del campo di input, si riflette sull'ambito ...
.
... Ma quando nidivo la vista / stato, il valore sull'ambito mantiene il suo valore iniziale, ma mi aspetto che venga modificato in base al valore del campo di input durante la sovrascrittura.
var myApp = angular.module('myApp', ['ui.router', 'myComponents'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.
state('home', {
abstract: true,
url: '',
template: 'Nested View:<div ui-view></div>',
controller: 'myController'
}).
state('home.detail', {
url: '',
template: '<my-filter text-filter="theFilter"></my-filter><button ng-click="inspect()">inspect</button>{{ theFilter |json}}'
});;
}]);
var components = angular.module('myComponents', []);
components.directive('myFilter', [function () {
return {
restrict: 'E',
template: '<input type="text" name="filter" ng-model="textFilter">',
scope: {
textFilter: '='
}
};
}]);
components.controller('myController', ['$scope', function ($scope) {
$scope.theFilter = 'initial filter';
$scope.inspect = function () {
alert($scope.theFilter);
}
}]);
.
Vista:
<div ng-app="myApp" >
<div ui-View></div>
</div>
.
Qui, il testo sull'ambito (vedi controller) rimane lo stesso.
Qualche idea come posso ottenere lo stesso risultato con le viste nidificate come nel primo esempio?
PS: la direttiva deve rimanere riutilizzabile
Soluzione
Questo è legato a un problema comune.Come menzionato in questo video angolare js - best practice (29:19) e spiegato qui: Scope annidati in JS angolare
."Ogni volta che hai il modello NG, è necessario essere un punto lì da qualche parte. Se non hai un punto, lo stai facendo male."
Quindi il controller dovrebbe creare un oggetto:
components.controller('myController', ['$scope', function($scope) {
// here theFilter is an object
// with property value
$scope.theFilter = { value : 'initial filter'};
$scope.inspect = function() {
alert($scope.theFilter.value);
}
}]);
.
E il modello dovrebbe funzionare con un oggetto con proprietà value
:
components.directive('myFilter', [function() {
return {
restrict: 'E',
template: '<input type="text" name="filter" ng-model="textFilter.value">',
scope: {
textFilter: '='
}
};
}]);
.
The Dated jsfiddle