如何在 AngularJs 中重新加载/重新编译/刷新指令?
How to reload / recompile / refresh directive in AngularJs?
我安装了 malhar-angular-dashboard 模块是为了使用小部件。在我配置我的 options 之后,dashboard-layouts 指令工作正常并且在视图中显示我的小部件。如果我在指令编译后更改控制器中的 options,我会收到此错误:
Widget fromTimeout is not found. undefined
HTML
<div ng-controller="widgetCtrl">
<div class="row">
<div class="col-md-12" style="background:#B8B7C9;">
<div ng-if="layoutOptions"
dashboard-layouts="layoutOptions"
class="dashboard-container"
template-url="views/dashboards/widget-area/customDashboardLayout.tmpl.html">
</div>
</div>
</div>
选择小部件 - 按钮
<div class="btn-group" ng-if="!options.widgetButtons">
<span class="dropdown" on-toggle="toggled(open)">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<span class="fa fa-bars"></span> Chose widget
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="widget in layoutOptions.widgetDefinitions"> <!-- initial was : widget in widgetDefs -->
<a href="#" ng-click="addWidgetInternal($event, widget);" class="dropdown-toggle"><span class="label label-primary">{{widget.name}}</span></a>
</li>
</ul>
</span>
</div>
JavaScript 控制器
// layout with explicit save
$scope.layoutOptions = {
storageId: 'demo-layouts-explicit-save',
storage: localStorage,
storageHash: 'fs4df4d51',
widgetDefinitions: $scope.myWidgets, // to be changed
layoutDefinitions:widgetDefs.REQUEST_ATTRIBUTES.layouts, // to be changed
defaultWidgets: [],
explicitSave: true,
defaultLayouts: [
{title: 'Layout 1', active: true, defaultWidgets: []}
]
};
$scope.newChanges = function(){
$scope.layoutOptions = {
storageId: 'demo-layouts-explicit-save',
storage: localStorage,
storageHash: 'fs4df4d51',
widgetDefinitions:[{name:"fromTimeout"}], //changed
layoutDefinitions:[], //changed
defaultWidgets: [],
explicitSave: true,
defaultLayouts: [
{title: 'Layout 1', active: true, defaultWidgets: []}
]
};
};
运行 申请
第一次加载(加载layoutOptions)
调用newChanges()函数后
结论
当我从 Chose widget 触发点击事件时,执行 addWidgetInternal($event, widget) 在 dashboard-layout 指令代码中导致我遇到这个问题:
scope.widgetDefs = new WidgetDefCollection(scope.options.widgetDefinitions);
scope.addWidget = function (widgetToInstantiate, doNotSave) {
if (typeof widgetToInstantiate === 'string') {
widgetToInstantiate = {
name: widgetToInstantiate
};
}
var defaultWidgetDefinition = scope.widgetDefs.getByName(widgetToInstantiate.name); // is undefined
if (!defaultWidgetDefinition) {
throw 'Widget ' + widgetToInstantiate.name + ' is not found.';
}
// Determine the title for the new widget
var title;
if (!widgetToInstantiate.title && !defaultWidgetDefinition.title) {
widgetToInstantiate.title = 'Widget ' + count++;
}
// Instantiation
var widget = new WidgetModel(defaultWidgetDefinition, widgetToInstantiate);
// Add to the widgets array
scope.widgets.push(widget);
if (!doNotSave) {
scope.saveDashboard();
}
return widget;
};
我想我需要重新编译指令才能访问我从控制器所做的新更改。有什么建议吗?
我没有使用 layout-dashboard
指令,但我使用了 dashboard
和 widget
指令。关于 Kendo UI 库的使用,我也为此苦苦挣扎了一段时间,并发现了一个强制重新编译小部件的 hack。
当我发现小部件指令代码中的 scope.compileTemplate() 函数调用时,它就开始了。
在我的例子中,我搜索了 Kendo 网格 class .k-grid,并在 angular 范围对象上找到了这个方法:$angular_scope.compileTemplate();
所以在我的刷新代码中,我首先在 DOM(另一个 hack)中查找任何 Kendo 网格:
var grids = $(angular.element(document.getElementById('dash'))).find('.k-grid');
然后我使用 _.each() 迭代 DOM 元素:
_.each(grids, function (elem) {
var grid = $(elem).parent().find('.k-grid').data('kendoGrid');
// add'l code omitted...
if (grid) {
grid.$angular_scope.compileTemplate(); // *** COMPILE TEMPLATE ***
}
});
它不是很优雅,但是当我动态换出小部件定义的 templateURL 属性 时,它确实会重新编译我的 HTML 代码。
祝你好运,
鲍勃
我安装了 malhar-angular-dashboard 模块是为了使用小部件。在我配置我的 options 之后,dashboard-layouts 指令工作正常并且在视图中显示我的小部件。如果我在指令编译后更改控制器中的 options,我会收到此错误:
Widget fromTimeout is not found. undefined
HTML
<div ng-controller="widgetCtrl">
<div class="row">
<div class="col-md-12" style="background:#B8B7C9;">
<div ng-if="layoutOptions"
dashboard-layouts="layoutOptions"
class="dashboard-container"
template-url="views/dashboards/widget-area/customDashboardLayout.tmpl.html">
</div>
</div>
</div>
选择小部件 - 按钮
<div class="btn-group" ng-if="!options.widgetButtons">
<span class="dropdown" on-toggle="toggled(open)">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<span class="fa fa-bars"></span> Chose widget
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="widget in layoutOptions.widgetDefinitions"> <!-- initial was : widget in widgetDefs -->
<a href="#" ng-click="addWidgetInternal($event, widget);" class="dropdown-toggle"><span class="label label-primary">{{widget.name}}</span></a>
</li>
</ul>
</span>
</div>
JavaScript 控制器
// layout with explicit save
$scope.layoutOptions = {
storageId: 'demo-layouts-explicit-save',
storage: localStorage,
storageHash: 'fs4df4d51',
widgetDefinitions: $scope.myWidgets, // to be changed
layoutDefinitions:widgetDefs.REQUEST_ATTRIBUTES.layouts, // to be changed
defaultWidgets: [],
explicitSave: true,
defaultLayouts: [
{title: 'Layout 1', active: true, defaultWidgets: []}
]
};
$scope.newChanges = function(){
$scope.layoutOptions = {
storageId: 'demo-layouts-explicit-save',
storage: localStorage,
storageHash: 'fs4df4d51',
widgetDefinitions:[{name:"fromTimeout"}], //changed
layoutDefinitions:[], //changed
defaultWidgets: [],
explicitSave: true,
defaultLayouts: [
{title: 'Layout 1', active: true, defaultWidgets: []}
]
};
};
运行 申请
第一次加载(加载layoutOptions)
调用newChanges()函数后
结论
当我从 Chose widget 触发点击事件时,执行 addWidgetInternal($event, widget) 在 dashboard-layout 指令代码中导致我遇到这个问题:
scope.widgetDefs = new WidgetDefCollection(scope.options.widgetDefinitions);
scope.addWidget = function (widgetToInstantiate, doNotSave) {
if (typeof widgetToInstantiate === 'string') {
widgetToInstantiate = {
name: widgetToInstantiate
};
}
var defaultWidgetDefinition = scope.widgetDefs.getByName(widgetToInstantiate.name); // is undefined
if (!defaultWidgetDefinition) {
throw 'Widget ' + widgetToInstantiate.name + ' is not found.';
}
// Determine the title for the new widget
var title;
if (!widgetToInstantiate.title && !defaultWidgetDefinition.title) {
widgetToInstantiate.title = 'Widget ' + count++;
}
// Instantiation
var widget = new WidgetModel(defaultWidgetDefinition, widgetToInstantiate);
// Add to the widgets array
scope.widgets.push(widget);
if (!doNotSave) {
scope.saveDashboard();
}
return widget;
};
我想我需要重新编译指令才能访问我从控制器所做的新更改。有什么建议吗?
我没有使用 layout-dashboard
指令,但我使用了 dashboard
和 widget
指令。关于 Kendo UI 库的使用,我也为此苦苦挣扎了一段时间,并发现了一个强制重新编译小部件的 hack。
当我发现小部件指令代码中的 scope.compileTemplate() 函数调用时,它就开始了。
在我的例子中,我搜索了 Kendo 网格 class .k-grid,并在 angular 范围对象上找到了这个方法:$angular_scope.compileTemplate();
所以在我的刷新代码中,我首先在 DOM(另一个 hack)中查找任何 Kendo 网格:
var grids = $(angular.element(document.getElementById('dash'))).find('.k-grid');
然后我使用 _.each() 迭代 DOM 元素:
_.each(grids, function (elem) {
var grid = $(elem).parent().find('.k-grid').data('kendoGrid');
// add'l code omitted...
if (grid) {
grid.$angular_scope.compileTemplate(); // *** COMPILE TEMPLATE ***
}
});
它不是很优雅,但是当我动态换出小部件定义的 templateURL 属性 时,它确实会重新编译我的 HTML 代码。
祝你好运, 鲍勃