gpt4 book ai didi

javascript - knockout : get reference to component A to call one of A's function from component B?

转载 作者:行者123 更新时间:2023-11-30 11:46:41 25 4
gpt4 key购买 nike

使用了 Yeoman 的 Knockout 生成器(大约 2015 年初),它包含在 require.js 和 router.js 中。只是使用 KO 的装载机。

我正在尝试从组件“b” 调用组件“a”中的函数(ko.observable 或不)。下面所有的虚构尝试仅仅是:

// In componentB:

ComponentA.sayFoo();

阅读关于组件和加载器的 KO 文档,被黑了几个小时,等等。我不想说 postal.js 的开销 - 也无法获得订阅(KO pub/sub)工作 - 我猜出于同样的原因:以这种方式设置的 View 模型没有相互引用(?) - 所以一个模块中的订阅者看不到另一个模块中的发布者(对吗?)(......有点在我头上 %-)

1) 这是因为模块之间看不到彼此……生成的代码没有将 KO 内容放在全局命名空间中吗?

2) 尝试从一个模块到达另一个模块,似乎取决于通过回调参数获取引用,使用下面的函数,或者这是不正确的? :

  ko.components.get (name, callback) ;

startup.js 使用 require 看起来像这样:

define(['jquery', 'knockout', './router', 'bootstrap', 'knockout-projections'], function($, ko, router) {

// Components can be packaged as AMD modules, such as the following:

ko.components.register('component-a', { require: 'components/a/component-a' });
ko.components.register('component-b', { require: 'components/b/component-b' });

// [Scaffolded component registrations will be inserted here. To retain this feature, don't remove this comment.]
// [Scaffold component's N/A (I think?)]

// Start the application
ko.applyBindings({ route: router.currentRoute });
});

(component) module A 很简单,像这样:

define(['knockout', 'text!./component-a'], function(ko, templateMarkup) {

function ComponentA (params) { console.log ('CompA'); } ;

ComponentA.prototype.sayFoo = function () { console.log ('FOO!'); } ;
ComponentA.prototype.dispose = function(){};

return { viewModel: ComponentA, template: templateMarkup };
});

同样,模块B是:

define(['knockout', 'text!./component-b'], function(ko, templateMarkup) {

function ComponentB (params) { console.log ('Compb'); } ;

ComponentB.prototype.doFoo = function () {
//// B Needs to fire ComponentA.foo() … SEE CODE ATTEMPT BELOW
};

ComponentB.prototype.dispose = function(){};

return { viewModel: ComponentB, template: templateMarkup };
});

所以这就是我卡住的地方:

  ComponentB.prototype.doFoo  = function () { 
ko.components.get ('component-a', ( function (parms) {
console.log ('parms.viewModel : ' + parms.viewModel );
// parms.viewModel is (unexpectedly) undefined ! So how to get the ref?
console.log ('parms.template : ' + parms.template );
// does have expected html objects, eg. [object HTMLwhatever], [object HTML...]
})) ;

这应该很简单,或者我愚蠢地遗漏了一些明显的东西!?

也许模块需要以不同方式定义/设置?

任何建议都会有所帮助!谢谢

最佳答案

这不是您通常在 knockout 组件之间进行通信的方式。

您的选择是:

1) 使用https://github.com/rniemeyer/knockout-postbox .这可能是最好的选择,因为它与 knockout 很好地结合在一起。它有详细的文档记录,如果您在设置时遇到问题,可以随时在此处寻求帮助。

2) 使用任何其他全局 javascript EventBus(f.i. postal.js)并发出/订阅组件中的事件。

3) 让您的根 ViewModel 将公共(public)可观察对象作为参数传递给每个组件 - 这样每个组件都可以修改/订阅相同的可观察对象。

4) (可能是你想要的,尽管是最差的缩放解决方案)如果你给不同的组件提供 id,你可以使用 ko.dataFor(document.getElementById("id")) 直接访问组件的属性和方法。

编辑:回应评论:

I haven't been able to determine what / where the root view model is: ko.applyBindings({ route: router.currentRoute }) is the clue, but router.js is convoluted. Suggestions on how to determine that?

完全正确 - 在您的情况下 { route: router.currentRoute } 对象是您的根 ViewModel。它目前只有一个名为 route 的属性,但您绝对可以扩展它。

例如:

var rootViewModel = {
route: router.currentRoute,
mySharedObservable: ko.observable('hi!')
}

ko.applyBindings(rootViewModel);

然后您可以像这样将可观察对象作为参数传递给多个组件:

<div id="component-a" data-bind="component: { name: 'component-a', params: {router: $root.router, mySharedObservable: $root.mySharedObservable} }"></div>
<div id="component-b" data-bind="component: { name: 'component-b', params: {router: $root.router, mySharedObservable: $root.mySharedObservable} }"></div>

最后,您可以像这样在组件中使用新的可观察对象:

function ComponentB (params) { 
this.mySharedObservable = params && params.mySharedObservable;
console.log(this.mySharedObservable());// This should log 'hi!'
};

您现在可以订阅可观察对象、更改它等等。它将在组件之间共享,因此更改一个组件将触发所有组件中的订阅。

关于javascript - knockout : get reference to component A to call one of A's function from component B?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40753619/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com