我在 AngularJS 项目中使用 ui-router,其中有一个包含自定义指令的嵌套视图。该指令呈现一个输入字段(假设是一个过滤字段),其值应该与控制器的范围同步。


当视图/状态未嵌套时,这对于该指令非常有效:

jsFiddle /未嵌套/按预期工作

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>

这里,范围(参见控制器)上的文本保持不变。

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

附:该指令需要保持可重用性

jsFiddle / 嵌套 / 未按预期工作

有帮助吗?

解决方案

这与一个常见问题有关。正如本视频中提到的 Angular JS - 最佳实践 (29:19),并解释如下: Angular JS 中的嵌套作用域

“只要你有 ng-model,那里就一定有一个点。如果你没有一个点,那么你就做错了。”

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top