Aurelia:视图和视图模型的继承
Aurelia: Inheritance of view and view-model
我正在构建一个 Aurelia 应用程序,它基本上允许用户为不同的资源显示不同的列表。这些列表共享一些功能,例如具有搜索和刷新功能的工具栏以及分页资源列表。
我为单个资源创建了这个,一切都很顺利,但我现在需要复制大部分 TypeScript 代码以及 HTML 其他资源列表。我决定采用不同的方法,创建一个带有一些命名视图槽和抽象视图模型的自定义元素。这适用于第一个 运行,但在操作列表后它会立即停止更新插槽内容。
有没有办法实现我想要做的事情?
如有任何帮助,我们将不胜感激。
旁注:我试图创建一个简单的 Gist 来演示这个问题,但我能找到的最新 CDN 版本似乎还不支持视图槽(我无法让它工作)。 :(
基本上我想做的是:
list.html
<template>
<div>list: ${counter}</div>
<slot></slot>
<button click.delegate="load()">Increase counter</button>
</template>
list.ts
import { autoinject } from 'aurelia-dependency-injection';
import { customElement } from 'aurelia-templating';
@customElement('list')
@autoinject
export abstract class List {
public abstract counter;
public abstract load();
}
resource.html
<template>
<require from="./list"></require>
<list>
<div>resource: ${counter}</div>
</list>
</template>
resource.ts
import { autoinject } from 'aurelia-dependency-injection';
import { List } from './list';
@autoinject
export class App extends List {
public counter = 0;
constructor() {
super();
}
public load() {
this.counter++;
}
}
这给出了以下输出:
list: 0
resource: 0
<button>Increase counter</button>
单击该按钮后,它应该同时增加列表和资源计数器,但它仍然显示资源“0”。
我的猜测是按钮正在调用抽象父 class 上的加载函数,该函数没有实现,因此什么也不做。将按钮更改为子 class 会起作用,但并不能真正帮助我实现代码减少目标。我怎样才能继续使用实施者的(资源)绑定上下文?有办法吗?还是我完全偏离了轨道?
编辑
所以我找到了解决它的方法,但感觉不对。我更改了 List
中的以下位:
@bindable({defaultBindingMode: bindingMode.twoWay}) public abstract counter:number;
然后在resource
HTML:
<list counter.bind="counter">
<div>users: ${counter}</div>
</list>
这样它就同步了 counter
属性 的绑定上下文。如果有一种方法可以告诉 List 根本没有自己的绑定上下文,我会更愿意,因为这在理论上会导致很多很多可绑定对象。有谁知道我如何告诉 List
继承绑定上下文?
编辑 2
为之前的 EDIT 找到了另一个解决方法,删除了可绑定行为并在 List
组件中实现了 bind
回调。这使我可以访问父绑定上下文作为第一个参数。我在本地保存在 List
组件中,然后在 counter
属性 更改时手动更新父绑定上下文。这仍然是一种解决方法,因为这会使 List
组件变得非常大,但让我不必担心资源中的绑定。 List
现在看起来像这样:
import { customElement } from 'aurelia-templating';
import { autoinject } from 'aurelia-dependency-injection';
import { observable } from 'aurelia-binding';
@customElement('list')
@autoinject
export abstract class List {
private parentContext;
@observable public abstract counter:number;
bind(bindingContext) {
this.parentContext = bindingContext;
}
counterChanged(newValue) {
if (this.parentContext) this.parentContext.counter = newValue;
}
public abstract load();
}
我仍然对完全删除 List
组件的绑定上下文并让它继承父绑定上下文的方法感兴趣。
Note instruction.inheritBindingContext 在这个 GitHub issue 中提到的就像 one-time
初始继承,因此对我来说没有用,但是可能对其他人有用。
看看这个博客post
Aurelia Dynamic Compose
使用 compose 和 v-model 和 model,你可以在同一个列表中有不同的自定义元素
在 Edit 2 之后,当我实施了多个资源列表时,我仍然遇到问题。它似乎在执行各种功能 x 次。因此,我不再手动同步绑定上下文,而是只更新父(资源)上下文,如下所示:
List.ts
import { customElement } from 'aurelia-templating';
@customElement('list')
export abstract class List {
public parentContext;
public abstract counter:number;
bind(bindingContext) {
this.parentContext = bindingContext;
}
public abstract load();
}
List.html
<template>
<div>list: ${parentContext.counter}</div>
<slot></slot>
<button click.delegate="parentContext.load()">Increase counter</button>
</template>
这不仅降低了我的 List
的复杂性,而且更有意义并且不易出错。
我正在构建一个 Aurelia 应用程序,它基本上允许用户为不同的资源显示不同的列表。这些列表共享一些功能,例如具有搜索和刷新功能的工具栏以及分页资源列表。
我为单个资源创建了这个,一切都很顺利,但我现在需要复制大部分 TypeScript 代码以及 HTML 其他资源列表。我决定采用不同的方法,创建一个带有一些命名视图槽和抽象视图模型的自定义元素。这适用于第一个 运行,但在操作列表后它会立即停止更新插槽内容。
有没有办法实现我想要做的事情?
如有任何帮助,我们将不胜感激。
旁注:我试图创建一个简单的 Gist 来演示这个问题,但我能找到的最新 CDN 版本似乎还不支持视图槽(我无法让它工作)。 :(
基本上我想做的是:
list.html
<template>
<div>list: ${counter}</div>
<slot></slot>
<button click.delegate="load()">Increase counter</button>
</template>
list.ts
import { autoinject } from 'aurelia-dependency-injection';
import { customElement } from 'aurelia-templating';
@customElement('list')
@autoinject
export abstract class List {
public abstract counter;
public abstract load();
}
resource.html
<template>
<require from="./list"></require>
<list>
<div>resource: ${counter}</div>
</list>
</template>
resource.ts
import { autoinject } from 'aurelia-dependency-injection';
import { List } from './list';
@autoinject
export class App extends List {
public counter = 0;
constructor() {
super();
}
public load() {
this.counter++;
}
}
这给出了以下输出:
list: 0
resource: 0
<button>Increase counter</button>
单击该按钮后,它应该同时增加列表和资源计数器,但它仍然显示资源“0”。 我的猜测是按钮正在调用抽象父 class 上的加载函数,该函数没有实现,因此什么也不做。将按钮更改为子 class 会起作用,但并不能真正帮助我实现代码减少目标。我怎样才能继续使用实施者的(资源)绑定上下文?有办法吗?还是我完全偏离了轨道?
编辑
所以我找到了解决它的方法,但感觉不对。我更改了 List
中的以下位:
@bindable({defaultBindingMode: bindingMode.twoWay}) public abstract counter:number;
然后在resource
HTML:
<list counter.bind="counter">
<div>users: ${counter}</div>
</list>
这样它就同步了 counter
属性 的绑定上下文。如果有一种方法可以告诉 List 根本没有自己的绑定上下文,我会更愿意,因为这在理论上会导致很多很多可绑定对象。有谁知道我如何告诉 List
继承绑定上下文?
编辑 2
为之前的 EDIT 找到了另一个解决方法,删除了可绑定行为并在 List
组件中实现了 bind
回调。这使我可以访问父绑定上下文作为第一个参数。我在本地保存在 List
组件中,然后在 counter
属性 更改时手动更新父绑定上下文。这仍然是一种解决方法,因为这会使 List
组件变得非常大,但让我不必担心资源中的绑定。 List
现在看起来像这样:
import { customElement } from 'aurelia-templating';
import { autoinject } from 'aurelia-dependency-injection';
import { observable } from 'aurelia-binding';
@customElement('list')
@autoinject
export abstract class List {
private parentContext;
@observable public abstract counter:number;
bind(bindingContext) {
this.parentContext = bindingContext;
}
counterChanged(newValue) {
if (this.parentContext) this.parentContext.counter = newValue;
}
public abstract load();
}
我仍然对完全删除 List
组件的绑定上下文并让它继承父绑定上下文的方法感兴趣。
Note instruction.inheritBindingContext 在这个 GitHub issue 中提到的就像 one-time
初始继承,因此对我来说没有用,但是可能对其他人有用。
看看这个博客post Aurelia Dynamic Compose 使用 compose 和 v-model 和 model,你可以在同一个列表中有不同的自定义元素
在 Edit 2 之后,当我实施了多个资源列表时,我仍然遇到问题。它似乎在执行各种功能 x 次。因此,我不再手动同步绑定上下文,而是只更新父(资源)上下文,如下所示:
List.ts
import { customElement } from 'aurelia-templating';
@customElement('list')
export abstract class List {
public parentContext;
public abstract counter:number;
bind(bindingContext) {
this.parentContext = bindingContext;
}
public abstract load();
}
List.html
<template>
<div>list: ${parentContext.counter}</div>
<slot></slot>
<button click.delegate="parentContext.load()">Increase counter</button>
</template>
这不仅降低了我的 List
的复杂性,而且更有意义并且不易出错。