gpt4 book ai didi

javascript - Durandal构造函数但还是想记住数据

转载 作者:行者123 更新时间:2023-11-29 18:15:37 25 4
gpt4 key购买 nike

假设我有以下 durandal 代码:

define(['durandal/app', 'plugins/http'], function (app) {
var vm = function(){
var self = this;
self.myData = ko.observableArray([]);
}

};
vm.activate = function() {
this.myData([]);
};
vm.deactivate = function(){

};
return vm;
};

我知道通过返回一个构造函数,每次激活 View 模型时,它都会返回一个新实例。

我的问题是:无论如何,当我访问时,如果有来自以前访问的 myData(),那么我不想设置 this.myData([]); 但要使用之前的 myData()

我知道通过返回一个单例对象可以做到,但是如果我想保留构造函数,我可以这样做吗?

另一个问题,如果你要获得新实例,那么在上面的代码中激活和停用有什么意义,因此无论如何保证一个“干净”的对象?

最佳答案

您可以采用多种方法,我在下面列举了这些方法。

对于下面的所有示例,请考虑项目 是选择的主题。

注入(inject)(无 View )

通过这种方法,我们将 ProjectsServices 模块(单例)注入(inject)到 Projects 模块(实例)中。但只有当 ProjectsServices 不提供一个或多个 View 时,这种方法才有效。下面,我将向您展示如果我们的服务模块本身也提供一个或多个 View ,我们可以做什么。

ProjectsServices ViewModel(单例)sevicesProjects.js

define('projectsServices', [],
function() {
var myData = null; //this may or may not be an observable

return {
myData: myData //we return an object literal, which is what makes this module a singleton
};
}
);

项目 ViewModel(实例)projects.js

define('projects', ['projectsServices'],
function(services) {

//Constructor
var Projects = function () {
this.myData = ko.observable(); //this may or may not be an observable
};

Projects.prototype.activate = function (activationData) {
this.myData(services.myData);
};

Projects.prototype.detached = function () {
services.myData = this.myData(); /store back to the services module for later use
};

return Projects; //we return a constructor function, which is what makes this module an instance
}
);

主机-客户端( View )

通过这种方法,Projects 模块由 ProjectsServices 模块组成,我们通过 activationData 上的可观察对象来回传递 myData。此外,这种方法假定服务模块不仅提供代码服务,还提供 View 服务。在其他表单上弹出的全局“添加联系人”表单是基于 View 的服务模块的示例。当然,“添加联系人” View 后面会有一个 viewModel,它表示用于添加联系人的代码服务。

ProjectsServices ViewModel(单例)servicesProjects.js

define('projectsServices', [],
function() {
var myData = ko.observable(); //should be an observable
}
);

ProjectsServices View servicesProjects.html

/*We bring in the Projects module through composition and pass in the observable, `myData`, itself (not `myData()`, but `myData`)*/
<div>
<div data-bind="compose: {model: 'viewmodels/projects', activationData: myData}">
</div>
</div>

项目 ViewModel(实例)projects.js

define('projects', [],
function() {

//Constructor
var Projects = function () {
this.myDataLocal = ko.observable(); //this may or may not be an observable
this.myDataFromServices = null;
};

Projects.prototype.activate = function (activationData) {
this.myDataFromServices = activationData
this.myDataLocal(activationData());
};

Projects.prototype.detached = function () {
this.myDataFromServices(this.myDataLocal()); /store back to the services module for later use
};

return Projects; //we return a constructor function, which is what makes this module an instance
}
);

项目 View projects.html

/*There are infinite number of ways to bind to your myDataLocal*/
<div>
<div data-bind="text: myDataLocal}">
</div>
</div>

发布-订阅

通过这种方法,我们通过 app 利用 Durandal 的内置发布/订阅工具。这种方法可以与上面给出的注入(inject)或主机客户端一起使用。该策略是从实例模块的 activate 处理程序发布请求消息,并在同一处理程序中接收回复消息,这两个消息的目的是请求和提供 myData(大概是早些时候保存下来的)。当我们准备好将 myData 保存回服务模块时,我们发送另一条消息,将 myData 作为有效负载。

ProjectsServices ViewModel(单例)servicesProjects.js

define('projectsServices', ['durandal/app'],
function(app) {
var
myData = null, //this may or may not be an observable

activate = function () {
app.on('requestForMyData').then( function () {
app.trigger('responseMyData', myData);
});
app.on('storeMyData').then( function (data) {
myData = data; //where 'data' is the payload
});
},

detached = function () {
app.off('requestForMyData');
app.off('storeMyData');
};

return {
myData: myData, //we return an object literal, which is what makes this module a singleton
activate: activate,
detached: detached
};
}
);

项目 ViewModel(实例)projects.js

define('projects', ['durandal/app'],
function(app) {

//Constructor
var Projects = function () {
this.myData = ko.observable(); //this may or may not be an observable
};

Projects.prototype.activate = function () {
var that = this;
app.on('responseMyData').then( function (data) {
that.myData(data);
});
app.trigger('requestForMyData'); //no payload
};

Projects.prototype.detached = function () {
app.trigger('storeMyData', this.myData());
app.off('responseMyData');
};

return Projects; //we return a constructor function, which is what makes this module an instance
}
);

在这种情况下, View 不会发生变化,因此此处未提供它们。

消息总线

此方法实际上与发布-订阅方法相同,只是我们使用的是客户端消息总线,例如 postal.js。正如您将看到的,它更精致。这也恰好是我们在生产中采用的方法。这种方法应该与上面的主机-客户端方法一起使用,只是我们只是传递消息 channel ,而不是数据本身。

  • 您可以下载 postal.js here .
  • 在 Github 上查看我 (@estaylorco) 与 Jim Cowart (@ifandelse) 的交流 here , here , 和 here .
  • 查看 postal.request-response 的 RC (我在下面使用它,因为它处于预览状态),以及我在那里的交流。 postal.request-response 是我要求的(双向 channel ),它仅适用于您正在使用的场景。它极大地简化了请求-响应场景。

ProjectsServices ViewModel(单例)servicesProjects.js

define('projectsServices', ['postal'],
function(postal) {
var
outletMessageChannel = 'someuniqueidentifier',
subscriptions = [],
myData = null, //this may or may not be an observable

activate = function () {
var that = this;
subscriptions.push(postal.subscribe({
channel: outletMessageChannel,
topic: 'request.mydata',
callback: function () {
postal.publish({
channel: outletMessageChannel,
topic: 'response.mydata',
data: that.myData
});
}
}));
subscriptions.push(postal.subscribe({
channel: outletMessageChannel,
topic: 'store.mydata',
callback: function (data) {
that.myData = data;
}
}));
},

detached = function () {
//I'm using underscore.js here, but you can use any approach to iterate over subscriptions
_.each(subscriptions, function(sub) {
sub.unsubscribe();
sub.callback = null;
sub = null;
});
subscriptions = null;
};

return {
myData: myData, //we return an object literal, which is what makes this module a singleton
activate: activate,
detached: detached
};
}
);

ProjectsServices View servicesProjects.html

/*We bring in the Projects module through composition and pass in the message channel*/
<div>
<div data-bind="compose: {model: 'viewmodels/projects', activationData: outletMessageChannel}">
</div>
</div>

项目 ViewModel(实例)projects.js

define('projects', ['postal'],
function(postal) {

//Constructor
var Projects = function () {
this.subscriptions = [];
this.outletMessageChannel = '';
this.myData = ko.observable(); //this may or may not be an observable
};

Projects.prototype.activate = function (activationData) {
this.outletMessageChannel = activationData;

var that = this;

subscriptions.push(postal.subscribe({
channel: this.outletMessageChannel,
topic: 'response.mydata',
callback: function (data) {
that.myData(data);
}
}));

postal.publish({
channel: this.outletMessageChannel,
topic: 'request.mydata',
data: null //no payload
});

};

Projects.prototype.detached = function () {
postal.publish({
channel: this.outletMessageChannel,
topic: 'store.mydata',
data: this.myData()
});

//I'm using underscore.js here, but you can use any approach to iterate over subscriptions
_.each(this.subscriptions, function(sub) {
sub.unsubscribe();
sub.callback = null;
sub = null;
});
this.subscriptions = null;
};

return Projects; //we return a constructor function, which is what makes this module an instance
}
);

请注意,Projects View 在这种情况下不会发生变化,因此此处未包含它。

关于javascript - Durandal构造函数但还是想记住数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23573100/

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