- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有以下 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 ,而不是数据本身。
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/
使用登录后,我想吐出用户名。 但是,当我尝试单击登录按钮时, 它给了我力量。 我看着logcat,但是什么也没显示。 这种编码是在说。 它将根据我在登录屏幕中输入的名称来烘烤用户名。 不会有任何密码。
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎是题外话,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或include a min
我是一名优秀的程序员,十分优秀!