我开始为具有不同过滤器小部件的搜索引擎编写一个durandal应用程序。我开始根据我在几个教程中看到的以下标准对视图模型进行编码(参见下面的示例,没有进一步说明),但是当我在“self”上分配一个具有相同名称的函数时,我遇到了问题。两种不同的视图模型。
我注意到当我开始复制现有的小部件时:在开始时结果集是混合的,函数不会被调用而没有任何错误......然后连续改变了可观察和函数名称,最后我只是通过改变它才能使它工作功能名称。 (例如self.facets - > self.facetsPA等) 我花了一段时间才找到它,很高兴知道按时完成项目,但这似乎不是一个好习惯,我觉得我可能做错了(通过分配自我对象的所有功能? )。
感谢您的一些解释。干杯,丹尼斯
define(['durandal/http', 'durandal/app', 'durandal/system','durandal/plugins/router'], function (http, app, system, router) {
var self = this;
var PatentOfficeItem = function(id,name) {
this.id = ko.observable(id);
this.name = ko.observable(name);
};
self.facetsPA = ko.observableArray([]);
self.selectablePAFacets = ko.computed(function() {
var results = [];
ko.utils.arrayForEach(self.facetsPA(), function(item) {
var o = item.key();
if (!self.officeExists(o))
results.push(item);
});
return results;
});
self.selectedPatentOffices = ko.observableArray([]);
self.officeToAdd = ko.observable("");
self.addPatentOffice = function(item) {
self.selectedPatentOffices.push(item);
};
self.removePatentOffice = function(item) {
self.selectedPatentOffices.remove(item);
var active = router.activeRoute();
if (active.hash == "#/results/show") {
app.trigger('PatentSearch:newQuery', 1);
}
};
self.officeExists = function(code) {
var result = false;
ko.utils.arrayForEach(self.selectedPatentOffices(), function(item) {
if (item.toString()==code.toString())
result = true;
});
return result;
};
self.onCheckFacet = function(f) {
var key = f.key();
var value = f.value();
var checked = f.checked();
if (!self.officeExists(key))
self.addPatentOffice(key);
app.trigger('PatentSearch:newQuery', 1);
};
self.onCheckOffice = function(f) {
//alert(JSON.stringify(f));
self.removePatentOffice(f);
app.trigger('PatentSearch:newQuery', 1);
};
self.getSetDifference2 = function(list1,list2) {
var difference = [];
var lookup = {};
for (var j in list2) {
var id = list2[j].id;
lookup[list2[j].id] = list2[j].name;
}
for (var i in list1) {
var id2 = list1[i].id;
//alert(id);
//if (lookup[id] == undefined ||lookup[id] === undefined) {
if (!(id2 in lookup)) {
difference.push(JSON.stringify(list1[i]));
//break;
}
}
//alert(JSON.stringify(difference));
return difference;
};
return {
activate: function () {},
viewAttached: function() {
setTimeout(function() {
$(".patentFacetMulti").typeahead({
source: function (query, process) {
return $.ajax({
url: "/assets/Content/patentoffices.json",
type: 'get',
data: {},
dataType: 'json',
success: function (result) {
var resultList = result.map(function (item) {
var aItem = { id: item.id, name: item.name };
return aItem;//JSON.stringify(aItem);
});
//return process(resultList);
return process(self.getSetDifference2(resultList,self.selectedPatentOffices()));
}
});
},
matcher: function (obj) {
var item = JSON.parse(obj);
return (~item.name.toLowerCase().indexOf(this.query.toLowerCase()) || ~item.id.toLowerCase().indexOf(this.query.toLowerCase()));
},
sorter: function (items) {
var beginswith = [], caseSensitive = [], caseInsensitive = [], item;
while (aItem = items.shift()) {
var item = JSON.parse(aItem);
if (!item.name.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(JSON.stringify(item));
else if (~item.name.indexOf(this.query)) caseSensitive.push(JSON.stringify(item));
else caseInsensitive.push(JSON.stringify(item));
}
return beginswith.concat(caseSensitive, caseInsensitive)
},
highlighter: function (obj) {
var item = JSON.parse(obj);
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
var n = item.name.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>'
});
var m = item.id.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>'
});
return ""+m+"- " + n;
},
updater: function (obj) {
var item = JSON.parse(obj);
//$('#IdControl').attr('value', item.id);
self.addOffice(item);
var active = router.activeRoute();
if (active.hash == "#/results/show") {
app.trigger('PatentSearch:newQuery', 1);
}
//$(this).val("");
return "";
}
});
},500);
},
selectedPatentOffices:selectedPatentOffices,
facetsPA:facetsPA
};
});
答案 0 :(得分:0)
如果您正在谈论Durandal对小部件的定义中的widgets
而不是那些需要返回构造函数以确保它们可以多次实例化的小部件。上面的例子改为返回单例。
http://durandaljs.com/documentation/Creating-A-Widget/
define(function(require) {
var widget = require('durandal/widget');
var ctor = function(element, settings) {
this.settings = settings;
};
ctor.prototype.getHeaderText = function(item) {
if (this.settings.headerProperty) {
return item[this.settings.headerProperty];
}
return item.toString();
};
ctor.prototype.afterRenderItem = function(elements, item) {
var parts = widget.getParts(elements);
var $itemContainer = $(parts.itemContainer);
$itemContainer.hide();
$(parts.headerContainer).bind('click', function() {
$itemContainer.toggle('fast');
});
};
return ctor;
});
答案 1 :(得分:0)
感谢您的回答。我的小部件必须是单例,因为我必须从其他视图模型访问和填充它们。我的问题也不是关于小部件(我更改了标题),我只是想知道为什么自我命名空间是全局的,当我使用上面的做法时,我不能在不同的视图模型上使用相同的方法名称两次。而我在这里可能做错了什么。由于这不是完全特定的问题,但一般来说更多的淘汰/ mvvm,所以也许标题之前是误导。
我主要是参考这篇文章(“管理这个”)
http://knockoutjs.com/documentation/computedObservables.html
我认为使用requirejs / knockout / durandal的整个意义是你可以拥有具有单独命名空间的视图模型,从而在javascript中产生更好的编程风格。作为自我全球化,对我来说没有意义,与不使用requirejs相比,我无法看到更长编码时间的优势。
我知道有更好的方法来构建具有durandal的小部件,但这暂时超出了我的范围。谢谢