我正在使用JSViews,Observables和TypeScript进行项目。 我打算处理几种语言,所以我有一个包含法语和英语版本的对象。一个带有静态方法的类,它返回名称集合和一个包含所有静态对象的数组。
我想在下拉列表中使用转换器显示对象以获取英文名称,我设法填写下拉列表并对更改做出反应,但我无法在下拉菜单中显示当前项目,而我不会#39 ;看看缺少什么。
你可以帮忙吗?我在这里制作了一个javascript示例: https://jsfiddle.net/ClaudeVernier/v093uqg0/var data = new dataModel();
for (var member in Harbors) {
if (typeof Harbors[member] == "object" && Harbors[member].name) {
data.harbors.push(Harbors[member]);
}
}
var myTmpl = $.templates("#harborTmpl");
myTmpl.link("#container", data);
$.observe(data, "*", myHandler);
然后,我需要弄清楚如何通过点击按钮来改变语言,如果您对此有所了解......它会有所帮助: - )
非常感谢, 克劳德
答案 0 :(得分:2)
查看Data-linked <select> elements - 包括<select> with converters部分。
您的代码:
<select id="cboHarbor" data-link="{{getName:activeHarbor}}">
不正确。您需要数据链接到activeHarbor。如果activeHarbor是一个字符串,您可以使用以下数据进行数据链接:
<select id="cboHarbor" data-link="activeHarbor">
但由于它是一个对象,您需要为每个港口对象提供某种字符串值属性,然后您可以将其用于每个选项值。然后,您将使用转换器在activeHarbor对象及其字符串值属性之间来回转换,以实现数据链接绑定行为。
例如,您可以使用当前语言中的名称作为字符串值,但使用基于当前语言更改的值有点奇怪。但是你需要一个getHarbor
转换器来转换回来从名称到港湾对象。这看起来像这样:
<select id="cboHarbor" data-link="{getName:activeHarbor:getHarbor}">
{^{for harbors}}
<option data-link="{getName:}"></option>
{{/for}}
</select>
或者,您可以使用数组中港口的索引,如下所示:
<select id="cboHarbor" data-link="{getIndex:activeHarbor:getHarbor}">
{^{for harbors}}
<option value="{{:#index}}" data-link="{getName:}"></option>
{{/for}}
</select>
转换器如下:
$.views.converters({
getIndex: function (harbor) {
return harbor.index;
},
getHarbor: function (index) {
return data.harbors[index];
},
getName: function (harbor) {
return harbor.name[data.languages[data.currentLanguage]];
}
});
如果您希望能够动态更改语言并将港口下拉菜单切换为新语言,则必须使getName
转换器依赖于当前语言,如下所示:
$.views.converters.getName.depends = [data, "currentLanguage"];
这是一个updated version of your jsfiddle完整的语言下拉菜单,用于切换语言。
更新:
关于depends
的{{1}},modified jsFiddle有这个:
getName
因此,您只需使用function getName(harbor) {
return harbor.name[data.languages[data.currentLanguage]];
}
$.views.converters({
getName: getName,
...
});
getName.depends = [data, "currentLanguage"];
函数作为转换函数,然后在您可以访问数据实例的上下文中(如果需要异步,则在getName
中),然后你分配了依赖:
done()
无需使用getName.depends = [data, "currentLanguage"];
答案 1 :(得分:0)
我遇到了在TypeScript中定义的对象上调用JSObservable.depends方法的问题。 我创建了一个小版本的网页,其中显示了城市的下拉列表,当前城市的名称以及该语言的选项。
我有语言和城市(港口)课程,两个IJSViews *接口,可以在转换器中编译代码
UnchartedGame类就是它发生的地方,它的GetName方法是转换器调用的方法,Init方法加载数据模型并加载模板。
模板链接后,我想设置依赖性,以便使用以下行设置城市下拉列表切换语言的内容: currentGame.GetName.depends = [currentGame,&#34; activeLanguage&#34;]; 但是对于&#34;编译器&#34;它不起作用,依赖不是GetName方法的方法!
我有三个文件:
的index.html
<script type="text/javascript" src="scripts/jquery-3.2.1.js"></script>
<script type="text/javascript" src="scripts/js/jsrender.js"></script>
<script type="text/javascript" src="scripts/js/jquery.observable.js"></script>
<script type="text/javascript" src="scripts/js/jquery.views.js"></script>
<script type="text/javascript" src="scripts/game/game.js"></script>
<div id="view" style="padding: 5px;">
<div id="optionsTmpl"></div>
</div>
options.tmpl.html
<select id="cboHarbor" data-link="{getIndex:activeHarbor:getHarbor}">
{^{for harbors}}
<option value="{{:#index}}" data-link="{getName:}"></option>
{{/for}}
</select>
<select id="cboLanguage" data-link="activeLanguage">
{^{props languages}}
<option>{{:key}}</option>
{{/props}}
</select>
game.ts
/// <reference path="../typings/jquery/jquery.d.ts" />
/// <reference path="../typings/jsrender/jsrender.d.ts" />
window.onload = () => {
let game: UnchartedGame;
this.game = new UnchartedGame();
$.views.converters({
getIndex: function (harbor) {
return harbor.index;
},
getHarbor: function (index) {
return this.ctx.root.harbors[index];
},
getName: this.game.GetName
});
this.game.load();
};
/*
* INTERFACES
*/
interface IDictionnary {
[idx: number]: string;
}
interface IHasName {
name: IDictionnary;
}
interface IJSViewsContextHolder {
ctx: IJSViewsRootHolder
}
interface IJSViewsRootHolder {
root: UnchartedGame
}
interface IHarbor {
index: number;
name: IDictionnary;
}
/*
* CLASSES
*/
class Languages {
["English"] = 0;
["French"] = 1;
}
class GameStrings {
static Brest: IDictionnary = {
["English"]: "Brest",
["French"]: "Brest"
};
static London: IDictionnary = {
["English"]: "London",
["French"]: "Londres"
};
static QuebecCity: IDictionnary = {
["English"]: "Quebec city",
["French"]: "Ville de Québec"
};
}
class Harbor implements IHarbor, IHasName {
public index: number = 0;
/* Methods */
constructor(public name: IDictionnary) {
}
}
class Harbors {
static Brest: IHarbor = new Harbor(
GameStrings.Brest
);
static London: IHarbor = new Harbor(
GameStrings.London
);
static QuebecCity: IHarbor = new Harbor(
GameStrings.QuebecCity
);
}
class UnchartedGame {
public activeLanguage: string = "English";
public languages: Languages = new Languages();
public activeHarbor: Harbor = null;
public harbors: Array<Harbor> = null;
public ctx: IJSViewsRootHolder;
constructor() {
}
GetName(harbor: IHarbor): any {
return harbor.name[(this as IJSViewsContextHolder).ctx.root.activeLanguage];
}
load() {
let idx: number = 0;
this.harbors = new Array<Harbor>();
for (var member in Harbors) {
Harbors[member].index = idx++;
if (!this.activeHarbor) {
this.activeHarbor = Harbors[member];
}
this.harbors.push(Harbors[member]);
}
this.linkTemplate("options", "#optionsTmpl", this).done(function (currentGame: UnchartedGame) {
//currentGame.GetName.depends = [currentGame, "activeLanguage"];
});
}
loadTemplate(tmplName: string) {
var deferredLoad = $.Deferred();
try {
var filePath: string = "../" + tmplName + ".tmpl.html";
$.get(filePath).then(function (templateText) {
$.templates(tmplName, templateText);
deferredLoad.resolve();
})
}
catch (e) {
deferredLoad.reject();
}
return deferredLoad.promise();
}
linkTemplate(tmplName: string, targetId: string, model: UnchartedGame) {
var deferredLink = $.Deferred();
this.loadTemplate(tmplName).done(
function () {
$.templates[tmplName].link(targetId, model);
deferredLink.resolve(model);
}
);
return deferredLink.promise();
}
}
我花了一些时间试图明确这一点,并试着让它适合这里,我希望它足够清楚,让你明白。
此致 克劳德
答案 2 :(得分:-1)
谢谢!
适用于港口,我之前和之后都没想过转换器。
对于本地化,因为我用TypeScript编写它,$ .views.converters.getName.depends没有编译所以我试图在linkTemplate之后添加它:
this.linkTemplate("options", "#optionsTmpl", this).done(
function (currentGame: UnchartedGame) {
$.observe(currentGame, "*", currentGame.gameModelChangeHandler);
$.views.converters["getName"].depends = [currentGame, "activeLanguage"];
}
);
它似乎不起作用,可能是因为[&#34; getName&#34;]还是其他地方?
这是一个我作为业余爱好开始的项目,它处于早期阶段,可以在这里看到:http://unchartedwaters2.azurewebsites.net/ : - )