gpt4 book ai didi

javascript - 如何确保指令的链接函数在 Controller 之前运行?

转载 作者:行者123 更新时间:2023-11-28 15:45:00 25 4
gpt4 key购买 nike

在我们的应用程序中,我们有一个通过简单路由加载的 View 。

$routeProvider
.when('/', {
template: require('./views/main.tpl.html'),
controller: 'mainCtrl'
})
.otherwise({
redirectTo: '/'
});

这关联了 mainCtrl具有 View 的 Controller 。 View 如下所示:

<left-rail>
<filter-sub-rail
id="filter-rail"
show-all-filter="isAdmin"
components="components">
</filter-sub-rail>
</left-rail>

<div class="endor-Page-content endor-Panel">
<action-bar
selected-components="selectedComponents"
toggleable-columns="toggleableColumns"
refresh-component-list="refreshComponentList()">
</action-bar>
<filter-pills></filter-pills>
<div class="js-endor-content endor-Panel-content endor-Panel-content--actionBarHeight">
<component-table
components="components"
selected-components="selectedComponents"
toggleable-columns="toggleableColumns">
</component-table>
</div>
<spinner id="cmSpinner" large="true" center="true"></spinner>
<modal></modal>
</div>

倒数第三行包含 <spinner>指示。该指令在加载数据时创建一个旋转图形。它有一个名为 spinnerApi 的关联 Angular 服务。 。 spinner指令使用spinner API注册spinner,允许其他服务注入(inject)spinner API并调用showhide方法,传入 ID,以显示/隐藏所需的微调器。

mainCtrl有一个函数在 Controller 运行时开始加载一些数据。

//spinnerApi.show('spinner1');
var data = Segment.query({
/*...truncated for brevity...*/
}, function () {
$scope.components = data;
spinnerApi.hide('spinner1');
});

您可以看到第一次调用 spinnerApi.show被注释掉了。这是因为此时 spinner 指令尚未运行其链接函数,并且 spinner 尚未向 API 注册。如果我取消注释该行,我会得到一个异常,因为还没有名为 spinner1 的微调器。但是,当回调从查询运行时,微调器可用并且调用成功。

在我开始在 Controller 中加载数据并避免这种竞争条件之前,如何确保微调器指令运行并使用 API 注册微调器?

最佳答案

换个 Angular 思考:

让您的 Controller 在范围上发布一个标志,表示 api 是否正在加载。将此标志传递给模板中的指令,并观察它是否在指令链接函数中切换微调器。在处理元素显示(DOM 渲染优化)时,优先使用 prelink 函数而不是 poSTLink 函数。在观察者外部的预链接时间设置微调器可见性!否则,它将等待第一个摘要循环发生,以隐藏您已经支付了显示一次费用的微调器!

如果多种行为可能影响此显示标志,请创建一个服务来保存此标志,在 Controller 的范围内发布此服务,并提供该标志作为模板中指令的输入。在指令中注入(inject)此服务意味着微调器指令与其可见性条件之间存在过多的耦合。

<小时/>

问题作者编辑:

这个答案给了我一个想法,效果很好,而且看起来相当简单。我不希望 Controller 或指令执行任何奇怪的等待逻辑,因此在 spinnerApi 服务中应该发生一些事情是有道理的(该指令应该可以在应用程序)。

这是我的 spinnerApi 服务,如果 spinnerId 尚未注册,则修改为队列隐藏/显示/切换事件。当 register 方法运行时,它会在队列中查找是否有任何事情要做。

module.exports = angular.module('shared.services.spinner-api', [])
// Simple API for easy spinner control.
.factory('spinnerApi', function () {
var spinnerCache = {};
var queue = {};
return {
// All spinners are stored here.
// Ex: { spinnerId: isolateScope }
spinnerCache: spinnerCache,

// Registers a spinner with the spinner API.
// This method is only ever really used by the directive itself, but
// the API could be used elsewhere if necessary.
register: function (spinnerId, spinnerData) {

// Add the spinner to the collection.
this.spinnerCache[spinnerId] = spinnerData;

// Increase the spinner count.
this.count++;

// Check if spinnerId was in the queue, if so then fire the
// queued function.
if (queue[spinnerId]) {
this[queue[spinnerId]](spinnerId);
delete queue[spinnerId];
}

},

// Removes a spinner from the collection.
unregister: function (spinnerId) {
if (!this.spinnerCache[spinnerId]) throw new Error('Spinner "' + spinnerId + '" does not exist.');
delete this.spinnerCache[spinnerId];
},

// Show a spinner with the specified spinnerId.
show: function (spinnerId) {
if (!this.spinnerCache[spinnerId]) {
queue[spinnerId] = 'show';
return;
}
this.spinnerCache[spinnerId].visible = true;
},

// Hide a spinner with the specified spinnerId.
hide: function (spinnerId) {
if (!this.spinnerCache[spinnerId]) {
queue[spinnerId] = 'hide';
return;
}
this.spinnerCache[spinnerId].visible = false;
},

// Hide/show a spinner with the specified spinnerId.
toggle: function (spinnerId) {
if (!this.spinnerCache[spinnerId]) {
queue[spinnerId] = 'toggle';
return;
}
this.spinnerCache[spinnerId].visible = !this.spinnerCache[spinnerId].visible;
},

// Show all spinners tracked by the API.
showAll: function () {
for (var key in this.spinnerCache) {
this.show(key);
}
},

// Hide all spinners tracked by the API.
hideAll: function () {
for (var key in this.spinnerCache) {
this.hide(key);
}
},

// Hide/show all spinners tracked by the API.
toggleAll: function () {
for (var key in this.spinnerCache)
this.spinnerCache[key].visible = !this.spinnerCache[key].visible;
},

// The number of spinners currently tracked by the API.
count: 0
};
});

关于javascript - 如何确保指令的链接函数在 Controller 之前运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22698112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com