将异步获取的数据传递给指令 [英] Passing asynchronously obtained data to a directive
问题描述
我目前有一个AngularJS controller
,基本上是通过$http.get()
调用异步获取一些JSON
,然后将获得的数据链接到某个范围变量.
I currently have an AngularJS controller
that is basically getting some JSON
asynchronously through a $http.get()
call, then linking the obtained data to some scope variable.
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
元素接收那些相同的作用域变量.
Then, I have a custom directive
which receives those same scope variables through a HTML
element.
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
未定义).
The problem is, since the $http.get()
is asynchronous, the directive is being badly initialised (e.g: $scope.pages.length - 1
is undefined).
尽管找到了一些似乎可以解决此问题的解决方案,但我找不到能为我解决该问题的任何方法.即,我试图观察变量,仅在检测到更改后才对变量进行初始化,如许多其他帖子中所建议的那样.为了进行测试,我使用了类似的方法:
I couldn't find anything that solved this problem for me, although there are some presented solutions that would seem to solve the case. Namely, I tried to watch the variables, only initialising the variables after detected changes, as suggested in many other posts. For testing, I used something like:
//... inside the directive's return{ }
link: function() {
scope.$watch('pages', function(pages){
if(pages)
console.log(pages);
});
}
我已经测试过了,没有多次调用$ watch函数(记录的值是undefined
),我认为这意味着它没有检测到变量值的变化.但是,我确认该值已更改.
I've tested it, and the $watch function wasn't called more than once (the logged value being undefined
), which, I assume, means it isn't detecting the change in the variable value. However, I confirmed that the value was being changed.
那么,这是什么问题?
推荐答案
在控制器中移动sidebar
对象的声明,并将范围绑定更改为=
.
Move the declaration for the sidebar
object in the controller and change the scope binding to =
.
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'
};
}]);
然后匹配指令名称并放括号.
Then match the directive name and drop the braces.
<mm-sidebar pages='interactionsCtrl.sidebar.pages'>
</mm-sidebar>
这是一个工作示例: http://plnkr.co/edit/VP79w4vL5xiifEWqAUGI
这篇关于将异步获取的数据传递给指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!