指令隔离范围不能与嵌套视图一起正常工作?(AngularJS/UI 路由器) [英] Directives isolated scope not working properly together with nested views? (AngularJS / UI Router)
问题描述
我在一个 AngularJS 项目中使用 ui-router,其中我有一个包含自定义指令的嵌套视图.该指令呈现一个输入字段(可以说是一个过滤器字段),它的值应该与控制器的范围同步.
<小时>当视图/状态不是嵌套时,这适用于此指令:
var myApp = angular.module('myApp', ['ui.router', 'myComponents']).config(['$stateProvider', 函数 ($stateProvider) {$stateProvider.状态('家',{网址:'',模板:'<my-filter text-filter="theFilter"></my-filter><button ng-click="inspect()">inspect</button>{{ theFilter |json}}',控制器:'我的控制器'});}]);var components = angular.module('myComponents', []);components.directive('myFilter', [function () {返回 {限制:'E',模板:'<input type="text" name="filter" ng-model="textFilter">',范围: {文本过滤器:'='}};}]);components.controller('myController', ['$scope', function ($scope) {$scope.theFilter = '初始过滤器';$scope.inspect = 函数 () {警报($scope.theFilter);}}]);
查看:
<div ui-View></div>
当我更改输入字段的文本时,它会反映在范围上...
<小时>...但是当我嵌套视图/状态时,范围上的值保持其初始值,但我希望它在覆盖时根据输入字段的值进行更改.
var myApp = angular.module('myApp', ['ui.router', 'myComponents']).config(['$stateProvider', 函数 ($stateProvider) {$stateProvider.状态('家',{摘要:真实,网址:'',模板:'嵌套视图:',控制器:'我的控制器'}).状态('home.detail',{网址:'',模板:'<my-filter text-filter="theFilter"></my-filter><button ng-click="inspect()">inspect</button>{{ theFilter |json}}'});;}]);var components = angular.module('myComponents', []);components.directive('myFilter', [function () {返回 {限制:'E',模板:'<input type="text" name="filter" ng-model="textFilter">',范围: {文本过滤器:'='}};}]);components.controller('myController', ['$scope', function ($scope) {$scope.theFilter = '初始过滤器';$scope.inspect = 函数 () {警报($scope.theFilter);}}]);
查看:
<div ng-app="myApp" ><div ui-View></div>
此处,范围(请参阅控制器)上的文本保持不变.
知道如何使用嵌套视图获得与第一个示例相同的结果吗?
PS:指令需要保持可重用
这与一个常见问题有关.如本视频中所述angular JS - 最佳实践 (29:19),并在此处进行了解释: Angular JS 中的嵌套作用域
<块引用>每当你有 ng-model 时,就必须在某个地方有一个点.如果你没有一个点,你就做错了."
所以控制器应该创建一个对象:
components.controller('myController', ['$scope', function($scope) {//这里的过滤器是一个对象//带有属性值$scope.theFilter = { value : '初始过滤器'};$scope.inspect = function() {警报($scope.theFilter.value);}}]);
并且模板应该使用具有属性 value
的对象:
components.directive('myFilter', [function() {返回 {限制:'E',模板:'<input type="text" name="filter" ng-model="textFilter.value">',范围: {文本过滤器:'='}};}]);
更新的jsfiddle
I'm using ui-router in a AngularJS project where I have a nested view that contains a custom directive. This directive renders an input field (lets say a filter-field) and its value should be in sync with the controller's scope.
This works well for this directive, when the view/state not is nested:
jsFiddle / not nested / working as expected
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);
}
}]);
View:
<div ng-app="myApp">
<div ui-View></div>
</div>
When I change the input field's text, it gets reflected on the scope...
...but when I nest the view/state, the value on the scope keeps it's initial value but I expect it to get changed according to the input field's value when overwriting.
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);
}
}]);
View:
<div ng-app="myApp" >
<div ui-View></div>
</div>
Here, the text on the scope (see controller) remains the same.
Any idea how I can get the same result with nested views as in the first example?
PS: The directive needs to remain reusable
jsFiddle / nested / not working as expected
This is related to a common issue. As mentioned in this video angular JS - best practice (29:19), and explained here: Nested Scopes in Angular JS
"Whenever you have ng-model there's gotta be a dot in there somewhere. If you don't have a dot, you're doing it wrong."
So the controller should be creating an object:
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);
}
}]);
and the template should work with an object having property value
:
components.directive('myFilter', [function() {
return {
restrict: 'E',
template: '<input type="text" name="filter" ng-model="textFilter.value">',
scope: {
textFilter: '='
}
};
}]);
The upated jsfiddle
这篇关于指令隔离范围不能与嵌套视图一起正常工作?(AngularJS/UI 路由器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!