![](/img/trans.png)
[英]AngularJS $scope Undefined When Compiling Controller In Directive
[英]scope is undefined in AngularJS directive with ajax request in controller
我正在使用AngularJS大约一个星期,我遇到了一个我无法理解的自定义指令的问题。 我的主要目标是在一个指令中创建一个html表,其中json数据在带有$ http服务的控制器中加载。
我有一个模板供我查看。 如果我使用像ng-repeat或表达式这样的Angular指令,似乎数据被正确加载并绑定到范围,我可以渲染我的视图。
但是,如果我在文档根目录中使用自定义指令,则会在控制器发送请求之前触发它。 所以当我在链接函数scope.myData中使用范围是未定义的。 但是如果我在ng-repeat中使用自定义指令,我可以访问本地范围。 我不明白为什么Angular指令会在数据加载后触发,以及之前为什么会开火。 我错过了什么吗?
实际上,我的数据实际上比样本更复杂,我必须在自定义指令中分析它们以生成我的html表:make rowspan或colspan for certains属性,如示例数据中的group name。
任何帮助将是有用的,非常感谢提前。
这是我的示例代码。
app.js
angular.module('myApp', [
'ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/test', {templateUrl: 'partials/test.html', controller: 'TestCtrl'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
controllers.js
angular.module('myApp.controllers', []).
controller('TestCtrl',['$scope', '$http',function($scope, $http){
$http.get('data/test.json').success(function(data) {
$scope.myData = data;
});
}]) ;
的test.html
<!-- this works perfectly -->
<h3>{{myData.title}}</h3>
<table class="table table-condensed table-bordered">
<thead>
<tr>
<th ng-repeat="col in myData.cols">{{col.title}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in myData.rows">
<td>{{row.group}}</td>
<td ng-repeat="col in row.cols">{{col}}</td>
</tr>
</tbody>
</table>
<!-- does not work ! -->
<table test-table></table>
directives.js
angular.module('myApp.directives', []).
.directive('testTable', ['$compile', function(compile){
return{
link: function(scope,elm,attrs,ctrl){
for(var i = 0, l= scope.myData.rows.length; i<l; i++){
var tr = angular.element(['<tr>', '</tr>'].join(''));
console.log(tr);
for(var j = 0; j<scope.myData.cols.length; j++){
var td = angular.element(['<td>', String(scope.myData.rows[i].cols[j]), '</td>'].join(''));
tr.append(td);
}
elm.append(tr);
}
compile(elm.contents())(scope);
}
}
}]);
test.json
{
"title" : "This is a simple sample data.",
"cols" : [{"title":"Group Name"},{"title":"Col1"},{"title":"Col2"},{"title":"Col3"}],
"rows" : [
{"group" : "group A","cols":["Something","Something else","Other stuff"]},
{"group" : "group A","cols":["Something","Something else","Other stuff"]},
{"group" : "group A","cols":["Something","Something else","Other stuff"]},
{"group" : "group B","cols":["Something","Something else","Other stuff"]},
{"group" : "group B","cols":["Something","Something else","Other stuff"]}
]
}
link
功能只运行一次。 它不会等待您的ajax请求获取数据,并且在范围更改时不会更新。
这与模板中的{{databinding}}
形成对比,模板中的{{databinding}}
随着范围的变化而更新。
您可以查看$scope.$watch
,它允许您在特定范围属性更改时运行回调,如下所示:
scope.$watch('myData', function (newMyData) {
//Build the table and insert it into DOM
});
然而,使用{{databinding}}
和ng-repeat
将是更多的角度方法。
有几种方法可以做到这一点:
您可以尝试resolve
路由参数(在文档中找到它)。 这将延迟加载页面,直到解决了承诺。
你正在使用像jQuery一样的Angular - 不要这样做。 (这是Angular新手的常见问题 - 阅读这个很棒的答案 。)关于ng-repeat
如何看待变化的问题:简而言之, ng-repeat
监视范围变量并对变化采取行动。 你可以做类似的事情:
范围。$ watch(“myData”,function(newval){...});
如果你想设置rowspan-colspan, ng-repeat
的扩展语法可能会有所帮助:
<header ng-repeat-start="item in items">
...
<footer ng-repeat-end>
(查看这里的长例)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.