У меня есть пример веб-компонентов здесь https://github.com/brianlmerritt/knockout-babel-browserify-gulp
Типичный основной HTML с компонентами:
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h2>Three Component View Model Binding Test</h2>
</div>
<div class="panel-body">
<!-- THE GOAL OF THE PROJECT IS TO BIND EVERYTHING BEFORE AND AFTER THE FOLLOWING COMPONENT WITH centralViewModel -->
<!-- ###ko stopBinding: true -->
<div class="col-md-4">
<component-one></component-one>
</div>
<div class="col-md-4">
<component-two></component-two>
</div>
<div class="col-md-4">
<component-three></component-three>
</div>
<!-- ###/ko -->
<p>Note: if component one did not load above, then check your browser console for errors</p>
</div>
типичный компонент - обратите внимание, что написано в ES2015 (Новый Javascript)
const ko = require('knockout')
, CentralData = require('../../service-providers/central-data')
, CentralState = require('../../service-providers/central-state')
, template = require('./template.html');
const viewModel = function (data) {
//Make service providers accessible to data-bind and templates
this.CentralData = CentralData;
this.CentralState = CentralState;
this.componentName = 'Component One';
this.foo = ko.observable(`${this.componentName} Foo`);
this.bar = ko.observableArray(this.componentName.split(' '));
this.barValue = ko.observable("");
this.bar.push('bar');
this.addToBar = (stuffForBar) => {
if(this.barValue().length >= 1) {
this.bar.push(this.barValue());
CentralData.pushMoreData({firstName: this.componentName,secondName:this.barValue()});
}
};
this.CentralState.signIn(this.componentName);
if (CentralData.dataWeRetrieved().length < 10) {
var dataToPush = {firstName : this.componentName, secondName : 'Foo-Bar'};
CentralData.pushMoreData(dataToPush);
}
};
console.info('Component One Running');
module.exports = {
name: 'component-one',
viewModel: viewModel,
template: template
};
template.html:
<div>
<h1 data-bind="text: componentName"></h1>
<p>Foo is currently: <span data-bind="text: foo"></span></p>
<p>Bar is an array. It's values currently are:</p>
<ul data-bind="foreach: bar">
<li data-bind="text: $data"></li>
</ul>
<form data-bind="submit: addToBar">
<input type="text"
name="bar"
placeholder="Be witty!"
data-bind="attr: {id : componentName}, value : barValue" />
<button type="submit">Add A Bar</button>
</form>
<h2>Central State</h2>
<p>The following components are currently signed in to Central State Service Provider</p>
<ul data-bind="foreach: CentralState.signedInComponents()">
<li data-bind="text: $data"></li>
</ul>
<h2>Central Data</h2>
<p>The following information is available from Central Data Service Provider</p>
<table class="table table-bordered table-responsive table-hover">
<tr>
<th>Component Name</th><th>Second Value</th>
</tr>
<!-- ko foreach: CentralData.dataWeRetrieved -->
<tr>
<td data-bind="text: firstName"></td><td data-bind="text: secondName"></td>
</tr>
<!-- /ko -->
</table>
<h3>End of Component One!</h3>
</div>
app.js имеет компонентные привязок
const ko = require('knockout');
/**
* The modules that follow are singleton modules that do not appear to conflict with bindings
*
*/
const CentralData = require('./service-providers/central-data'); // Mock centralised data/model service
const CentralState = require('./service-providers/central-state'); // Mock centralised state service
/**
* Register knockout web components - these work, but conflict with any central bindings
*/
ko.components.register(
'component-one',
require('./components/component-one/component.js')
);
ko.components.register(
'component-two',
require('./components/component-two/component.js')
);
ko.components.register(
'component-three',
require('./components/component-three/component.js')
);
/**
* This code comes from http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html
*
* Telling Knockout to Skip Binding Part of a Page
*
* However, when used around a component, the component does not load/run!
*
*/
ko.bindingHandlers.stopBinding = {
init: function() {
return { controlsDescendantBindings: true };
}
};
ko.virtualElements.allowedBindings.stopBinding = true;
/**
* centralViewModel should be loadable for "all of the page not managed by components"
*
* That is the goal of the project, which I am failing in badly at the moment
*
*/
const centralViewModel = {
bindingWorked : ko.observable('The binding worked. KO view model centralViewModel has a this context and was bound to the html correctly')
};
console.info('app.js applying bindings...');
/**
* The next line should bind central viewmodel to everything, but conflicts with components!!
*/
ko.applyBindings(centralViewModel,document.body);
// ko.applyBindings(); // Pull in all of the components
/**
Note: to avoid binding issues, we should be able to add these html comments around each component
<!-- ko stopBinding: true -->
<component-name>
<!-- /ko -->
However - when we do, the components no longer work
*/
Не могли бы вы расширить ваш образец кода в [mcve]? – Jeroen
Я сделаю это, как только смогу! – Nate