隔离的指令范围与嵌套视图一起无法正常工作? (AngularJS / UI路由器)

时间:2014-04-13 13:17:35

标签: javascript angularjs angularjs-directive angularjs-scope angular-ui-router

我在AngularJS项目中使用ui-router,我有一个包含自定义指令的嵌套视图。 该指令呈现输入字段(比如说filter-field),其值应与控制器的作用域同步。


当视图/状态未嵌套时,这适用于此指令:

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

查看:

<div ng-app="myApp">
    <div ui-View></div>
</div>

当我更改输入字段的文本时,它会反映在范围...


...但是当我嵌套视图/状态时,作用域上的值保留了它的初始值,但我希望它在覆盖时根据输入字段的值进行更改。

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

查看:

<div ng-app="myApp" >
    <div ui-View></div>
</div>

此处,范围(请参阅控制器)上的文本保持不变。

我知道如何使用嵌套视图获得与第一个示例相同的结果吗?

PS:指令需要保持可重复使用

jsFiddle / nested / not working as expected

1 个答案:

答案 0 :(得分:1)

这与一个常见问题有关。正如此视频angular JS - best practice(29:19)中所述,并在此处进行了解释:Nested Scopes in Angular JS

  

“每当你有一个模型时,某处都会有一个点。如果你没有一个点,那你做错了。”

所以控制器应该创建一个对象:

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

并且模板应该与具有属性value的对象一起使用:

components.directive('myFilter', [function() {
    return {
        restrict: 'E',
        template: '<input type="text" name="filter" ng-model="textFilter.value">',
        scope: {
            textFilter: '='             
        }
    };          
}]);

提升jsfiddle