Aurelia - 多个 Enhance 语句
Aurelia - multiple Enhance statements
已更新解决方案 (28.03.2017):
http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/app-configuration-and-startup/8
已使用解决方案更新 Aurelia 文档(向下滚动一点)。
特别感谢 Charleh 的提示。
问题:
Aurelia 有这个很好的功能调用 enhance
,它可以帮助您使用 Aurelia 功能增强应用程序的特定部分。
但是我们可以在同一个页面上有多个增强语句吗?好像有问题。
示例:
任务:增强页面上的第一个组件,然后从服务器获取一些数据并使用服务器数据作为绑定上下文增强页面上的第二个组件
HTML
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<my-component1></my-component1>
<my-component2></my-component2>
</body>
</html>
JS
import { bootstrap } from 'aurelia-bootstrapper-webpack';
bootstrap(function(aurelia) {
aurelia.use
.standardConfiguration()
.globalResources("my-component1", "my-component2");
aurelia.start().then((app) => {
// Enhance first element
app.enhance(null, document.querySelector('my-component1'));
// Get some data from server and then enhance second element with binding context
getSomeDataFromServer().then((data) => {
app.enhance(data, document.querySelector('my-component2'));
});
});
});
结果:
在结果中我们将增强第一个组件,但是当第二个组件出现时,Aurelia 将尝试再次增强第一个组件!
这是因为 aurelia-framework.js
_configureHost
方法。
所以基本上当你开始 enhance
时,它会以你的元素作为应用程序宿主来启动这个方法:
Aurelia.prototype.enhance = function enhance() {
var _this2 = this;
var bindingContext = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var applicationHost = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
this._configureHost(applicationHost || _aureliaPal.DOM.querySelectorAll('body')[0]);
return new Promise(function (resolve) {
var engine = _this2.container.get(_aureliaTemplating.TemplatingEngine);
_this2.root = engine.enhance({ container: _this2.container, element: _this2.host, resources: _this2.resources, bindingContext: bindingContext });
_this2.root.attached();
_this2._onAureliaComposed();
resolve(_this2);
});
};
在 _configureHost
中,我们可以看到这个 if 语句,它只是检查我们的应用程序实例是否已经配置好主机,然后什么也不做。
Aurelia.prototype._configureHost = function _configureHost(applicationHost) {
if (this.hostConfigured) {
return;
}
...
问题
所以这里的实际问题是,任何增强元素都会自动成为应用程序宿主(根),当您尝试使用相同的 aurelia 实例增强另一个元素时,您最终只会增强第一个元素。
问题
当我想增强页面上的几个元素时,这是解决问题的方法吗?
这里有一个线索:
this.root = engine.enhance({container: this.container, element: this.host, resources: this.resources, bindingContext: bindingContext});
this.root.attached();
aurelia.enhance
只是包装了 TemplatingEngine
实例的 .enhance
方法。
您可以从容器中拉出 TemplatingEngine
并在其上调用 .enhance
并传递 bindingContext
因为 aurelia.enhance
就是这样做的(但添加了额外的 "host configure" 您已经通过第一个 .enhance
调用完成的步骤)。
所以那一点可能看起来像:
import { Container } from 'aurelia-dependency-injection';
let engine = Container.instance.get(TemplatingEngine);
engine.enhance({ container: Container.instance, element: document.querySelect('my-component2'), resources: (you might need to inject these too), bindingContext: someContext });
(免责声明:我没有测试上面的内容,所以它可能不准确 - 你可能还需要传递资源对象 - 你可以注入它或从容器中提取它 - 我相信类型只是Resources
)
但是 - 需要注意的一点:您的 my-component2
实际上不会是您的宿主元素 my-component1
的子元素。我不确定这是否会导致进一步的问题,但这只是一个想法。
我仍然很好奇为什么你想要 bootstrap 一个 Aurelia 实例,然后让它增强同一页面上的多个元素,而不是仅仅将所有服务器响应逻辑包装在组件的视图模型中本身?
也许您可以提供更多背景信息来说明这背后的原因?
我目前针对此问题的解决方法(感谢 Charleh 提供的线索):
import { bootstrap } from 'aurelia-bootstrapper-webpack';
import {TemplatingEngine} from "aurelia-framework";
let enhanceNode = function (app, node, bindingContext = null) {
let engine = app.container.get(TemplatingEngine);
let component = engine.enhance({container: app.container, element: node, resources: app.resources, bindingContext: bindingContext});
component.attached();
}
bootstrap(function(aurelia) {
aurelia.use
.standardConfiguration()
.globalResources("my-component1", "my-component2")
aurelia.start().then((app) => {
enhanceNode(document.querySelector('my-component1'));
enhanceNode(document.querySelector('my-component2'));
});
});
这样您就可以跳过应用程序的主机配置,并可以根据需要在页面上增强任意数量的自定义元素。
已更新解决方案 (28.03.2017):
http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/app-configuration-and-startup/8
已使用解决方案更新 Aurelia 文档(向下滚动一点)。
特别感谢 Charleh 的提示。
问题:
Aurelia 有这个很好的功能调用 enhance
,它可以帮助您使用 Aurelia 功能增强应用程序的特定部分。
但是我们可以在同一个页面上有多个增强语句吗?好像有问题。
示例:
任务:增强页面上的第一个组件,然后从服务器获取一些数据并使用服务器数据作为绑定上下文增强页面上的第二个组件
HTML
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<my-component1></my-component1>
<my-component2></my-component2>
</body>
</html>
JS
import { bootstrap } from 'aurelia-bootstrapper-webpack';
bootstrap(function(aurelia) {
aurelia.use
.standardConfiguration()
.globalResources("my-component1", "my-component2");
aurelia.start().then((app) => {
// Enhance first element
app.enhance(null, document.querySelector('my-component1'));
// Get some data from server and then enhance second element with binding context
getSomeDataFromServer().then((data) => {
app.enhance(data, document.querySelector('my-component2'));
});
});
});
结果:
在结果中我们将增强第一个组件,但是当第二个组件出现时,Aurelia 将尝试再次增强第一个组件!
这是因为 aurelia-framework.js
_configureHost
方法。
所以基本上当你开始 enhance
时,它会以你的元素作为应用程序宿主来启动这个方法:
Aurelia.prototype.enhance = function enhance() {
var _this2 = this;
var bindingContext = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var applicationHost = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
this._configureHost(applicationHost || _aureliaPal.DOM.querySelectorAll('body')[0]);
return new Promise(function (resolve) {
var engine = _this2.container.get(_aureliaTemplating.TemplatingEngine);
_this2.root = engine.enhance({ container: _this2.container, element: _this2.host, resources: _this2.resources, bindingContext: bindingContext });
_this2.root.attached();
_this2._onAureliaComposed();
resolve(_this2);
});
};
在 _configureHost
中,我们可以看到这个 if 语句,它只是检查我们的应用程序实例是否已经配置好主机,然后什么也不做。
Aurelia.prototype._configureHost = function _configureHost(applicationHost) {
if (this.hostConfigured) {
return;
}
...
问题 所以这里的实际问题是,任何增强元素都会自动成为应用程序宿主(根),当您尝试使用相同的 aurelia 实例增强另一个元素时,您最终只会增强第一个元素。
问题 当我想增强页面上的几个元素时,这是解决问题的方法吗?
这里有一个线索:
this.root = engine.enhance({container: this.container, element: this.host, resources: this.resources, bindingContext: bindingContext});
this.root.attached();
aurelia.enhance
只是包装了 TemplatingEngine
实例的 .enhance
方法。
您可以从容器中拉出 TemplatingEngine
并在其上调用 .enhance
并传递 bindingContext
因为 aurelia.enhance
就是这样做的(但添加了额外的 "host configure" 您已经通过第一个 .enhance
调用完成的步骤)。
所以那一点可能看起来像:
import { Container } from 'aurelia-dependency-injection';
let engine = Container.instance.get(TemplatingEngine);
engine.enhance({ container: Container.instance, element: document.querySelect('my-component2'), resources: (you might need to inject these too), bindingContext: someContext });
(免责声明:我没有测试上面的内容,所以它可能不准确 - 你可能还需要传递资源对象 - 你可以注入它或从容器中提取它 - 我相信类型只是Resources
)
但是 - 需要注意的一点:您的 my-component2
实际上不会是您的宿主元素 my-component1
的子元素。我不确定这是否会导致进一步的问题,但这只是一个想法。
我仍然很好奇为什么你想要 bootstrap 一个 Aurelia 实例,然后让它增强同一页面上的多个元素,而不是仅仅将所有服务器响应逻辑包装在组件的视图模型中本身?
也许您可以提供更多背景信息来说明这背后的原因?
我目前针对此问题的解决方法(感谢 Charleh 提供的线索):
import { bootstrap } from 'aurelia-bootstrapper-webpack';
import {TemplatingEngine} from "aurelia-framework";
let enhanceNode = function (app, node, bindingContext = null) {
let engine = app.container.get(TemplatingEngine);
let component = engine.enhance({container: app.container, element: node, resources: app.resources, bindingContext: bindingContext});
component.attached();
}
bootstrap(function(aurelia) {
aurelia.use
.standardConfiguration()
.globalResources("my-component1", "my-component2")
aurelia.start().then((app) => {
enhanceNode(document.querySelector('my-component1'));
enhanceNode(document.querySelector('my-component2'));
});
});
这样您就可以跳过应用程序的主机配置,并可以根据需要在页面上增强任意数量的自定义元素。