【发布时间】:2016-06-04 08:17:37
【问题描述】:
我正在开发一个“小部件”库,它创建一个带有可拖动、动态加载的小部件的仪表板。整体解决方案是使用 Angular。每个小部件都有一个 JavaScript 文件和一个 Jade 文件。对于我们的一些小部件,结果使用 ng-repeat 等角度指令。这是一个特定小部件生成的代码:
<tr ng-repeat="account in vmAccountList">
<td ng-click="showTransactions(account)">{{account.account.accountNumber}}</td>
<td ng-click="showTransactions(account)">{{account.account.accountDisplayName.defaultNormalAccountName}}</td>
<td ng-click="showTransactions(account)" ng-if="account.account.acctTypeId==1">{{account.account.runningBalance.amount | currency}}</td>
<td ng-click="showTransactions(account)" ng-if="account.account.acctTypeId==3">{{account.account.currentBalance.amount | currency}}</td>
<td ng-click="showTransactions(account)" ng-if="account.account.acctTypeId==4">{{account.account.currentBalance.amount | currency}}</td>
<td><a ng-click="deleteAccount(account.itemId);" class="btn btn-default btn xs">X</a></td>
</tr>
问题是 ng-repeat 永远不会被处理——生成的小部件只是呈现一个带有上面所有合并标签的单行,完全不知道数据。我尝试了许多不同的 $scope.$apply 和 $scope.$digest 组合——它们都不起作用。我收集到这个问题是因为当我的小部件被下载时,JADE 渲染和 JS 应用它可能在页面的生命周期中太“晚”了,无法使用 Angular 进程指令。
是否有一个命令可以手动告诉 Angular 去查找所有的 ng-repeats 并渲染它们?如果做不到这一点,有没有办法将东西插入到加载 aync 的 DOM 中并让 Angular 应用这些命令?
加载小部件和填充 DOM 的代码:
$.get('/v1/widget/' + name, (data) => {
var jadeCode = data;
$.get('/v1/widget/js/' + name, (data) => {
if(!w)
w = 2;
if(!h)
h = 1;
if(that._lastX + w > SDB.NumberOfVerticalLanes) {
that._lastX = 0;
that._lastY += h;
}
var retVal = new Widget(name, domId, that._lastX, that._lastY, w, h, '');
var processedWidget = eval(data + "(retVal)");
processedWidget._jadeFN = jade.compile(jadeCode);
var content = processedWidget._jadeFN(processedWidget.JadeScope);
//The 'content variable contains the markup I posted above at this point, and SetContent applies it to the DOM
processedWidget.SetContent(content);
});
});
上面sn-p中注释高亮的SetContent方法,就是简单的用jquery插入新的内容:
this.SetContent = (cnt) => {
this.Content = cnt;
$("#" + this.Id).html(cnt);
};
如果我的一些术语(特别是关于 Angular)不正确,我深表歉意,我只是对它有点熟悉,坦率地说,我不是一个忠实的粉丝。但是该项目使用它,所以我必须找到一种方法来让它工作。谢谢!
【问题讨论】:
-
据我了解,当您有 ng-repeat 时,它会在您的案例“vmAccountList”中为数组值设置一个观察者,因此当您更改它时它应该更新。如果由于某些奇怪的原因它没有,您可以在获取数据后尝试 $apply。
-
我都试过了——看来 Angular 根本不知道我的 ng-repeat,即使我更新 vmAccountList 或调用 $apply 它根本不会更新我的组件。我们知道,如果代码没有异步加载,它就可以工作——但是一旦我们加载它并将其动态添加到 DOM 中,ng-repeat 就会停止工作。
-
尝试在 processesWidget.SetContent 行之后添加 $scope.$apply()。如果这不起作用,那么我猜您的 html 替换正在删除该过程中的角度链接。需要完整的页面代码才能深入挖掘。
标签: javascript jquery angularjs dom