我目前有一个AngularJS controller,它基本上是JSON通过$http.get()调用异步获取的,然后将获取的数据链接到某个范围变量。
controller
JSON
$http.get()
controller代码的恢复版本:
mapsControllers.controller('interactionsController', ['$http', function($http) { var ctrlModel = this; $http.get("data/interactionsPages.json"). success(function(data) { ctrlModel.sidebar = {}; ctrlModel.sidebar.pages = data; }). error(function() {...}); }]);
然后,我有一个自定义directive,它通过一个HTML元素接收那些相同的作用域变量。
directive
HTML
directive代码的恢复版本:
mapsDirectives.directive('sidebar', function() { return { restrict : 'E', scope : { pages : '@' }, controller : function($scope) { $scope.firstPage = 0; $scope.lastPage = $scope.pages.length - 1; $scope.activePage = 0; //... }, link : function(scope) { console.log(scope.pages); }, templateURL : 'sidebar.html' } });
的恢复版本HTML:
<body> <div ng-controller='interactionsController as interactionsCtrl'> <mm-sidebar pages='{{interactionsCtrl.ctrlModel.sidebar.pages}}'> </mm-sidebar> </div> </body>
问题是,由于$http.get()是异步的,因此该指令已被严重初始化(例如:$scope.pages.length - 1未定义)。
$scope.pages.length - 1
尽管找到了一些似乎可以解决此问题的解决方案,但我找不到能为我解决该问题的任何方法。即,我试图观察变量,仅在检测到更改后才对变量进行初始化,如许多其他帖子所建议的那样。为了进行测试,我使用了类似的方法:
//... inside the directive's return{ } link: function() { scope.$watch('pages', function(pages){ if(pages) console.log(pages); }); }
我已经对其进行了测试,并没有多次调用$ watch函数(记录的值为undefined),我认为这意味着它没有检测到变量值的变化。但是,我确认该值已更改。
undefined
那么,这是什么问题呢?
sidebar在控制器中移动对象的声明,并将范围绑定更改为=。
sidebar
=
mapsDirectives.controller("interactionsController", ["$http", "$timeout", function($http, $timeout) { var ctrlModel = this; ctrlModel.sidebar = { pages: [] }; /* $http.get("data/interactionsPages.json"). success(function(data) { //ctrlModel.sidebar = {}; ctrlModel.sidebar.pages = data; }). error(function() {}); */ $timeout(function() { //ctrlModel.sidebar = {}; ctrlModel.sidebar.pages = ["one", "two"]; }, 2000); } ]); mapsDirectives.directive('mmSidebar', [function() { return { restrict: 'E', scope: { pages: '=' }, controller: function() {}, link: function(scope, element, attrs, ctrl) { scope.$watch("pages", function(val) { scope.firstPage = 0; scope.lastPage = scope.pages.length - 1; scope.activePage = 0; }); }, templateUrl: 'sidebar.html' }; }]);
然后匹配指令名称并删除花括号。
<mm-sidebar pages='interactionsCtrl.sidebar.pages'> </mm-sidebar>
这是一个工作示例:http : //plnkr.co/edit/VP79w4vL5xiifEWqAUGI