【问题标题】:KnockoutJS and PubSub to update observable array between viewsKnockoutJS 和 PubSub 更新视图之间的可观察数组
【发布时间】:2019-01-26 15:02:41
【问题描述】:

我有两个modalviews - MyModalViewA(父)和MyModalViewB(子)。

MyModalViewA 生成 MyModalViewB,作为自定义绑定,还有我需要更新的可观察数组。它看起来像:

(function () {

            'use strict';

            var
                window = __webpack_require__(/*! window */ 10),
                _ = __webpack_require__(/*! _ */ 2),
                $ = __webpack_require__(/*! $ */ 12),
                ko = __webpack_require__(/*! ko */ 3),
                key = __webpack_require__(/*! key */ 16),

                Enums = __webpack_require__(/*! Common/Enums */ 4),
                Utils = __webpack_require__(/*! Common/Utils */ 1),

                Links = __webpack_require__(/*! Common/Links */ 13),
                Remote = __webpack_require__(/*! Remote/User/Ajax */ 14),

                kn = __webpack_require__(/*! Knoin/Knoin */ 5),
                AbstractView = __webpack_require__(/*! Knoin/AbstractView */ 11),
                AttachmentModel = __webpack_require__(/*! Model/Attachment */ 86)
            ;

    function MyModalViewA()
    {
       ...some observables...
       //data response which must be updated
       this.rows= ko.observableArray([]);

       this.getResults = Utils.createCommand(this, function() 
       {
         kn.showScreenPopup(__webpack_require__(/*! View/Popup/SearchUsers */ 171),[oData]);
       }
    }

 kn.constructorEnd(this);
}

module.exports = MyModelViewA;

}());

然后MyModelViewB:

(function () {

            'use strict';

            var
                window = __webpack_require__(/*! window */ 10),
                _ = __webpack_require__(/*! _ */ 2),
                $ = __webpack_require__(/*! $ */ 12),
                ko = __webpack_require__(/*! ko */ 3),
                key = __webpack_require__(/*! key */ 16),

                Enums = __webpack_require__(/*! Common/Enums */ 4),
                Utils = __webpack_require__(/*! Common/Utils */ 1),

                Links = __webpack_require__(/*! Common/Links */ 13),
                Remote = __webpack_require__(/*! Remote/User/Ajax */ 14),

                kn = __webpack_require__(/*! Knoin/Knoin */ 5),
                AbstractView = __webpack_require__(/*! Knoin/AbstractView */ 11),
                AttachmentModel = __webpack_require__(/*! Model/Attachment */ 86)
  ;

        function MyModalViewB()
        {
           ...some observables...

        this.doSearch = Utils.createCommand(this, function() 
        {
           MyModelViewB.findUsers(userId);
        }

        kn.constructorEnd(this);
        }

        MyModelViewB.findUsers = function (userId)
        {
             //here I'm retriewing rows 
             //and I need I need to update rows from MyModalViewA
        }


    module.exports = MyModelViewB;

    }());

然后根据Whats the best way of linking/synchronising view models in Knockout? 的回答,我尝试使用PubSubMyModelViewA 更新this.rows= ko.observableArray([]);

为此,我已将 var postbox = ko.observable(); 添加到 MyModelViewA 构造函数变量。然后在MyModelViewA我加了

   postbox.subscribe(function(newValue) {
        this.rows.push(newValue);
    }, this);

MyModelViewB之后我添加了

this.results = ko.observableArray([]);
this.results.subscribe(function(newValue) {
    postbox.notifySubscribers(newValue);
});

但是当我将newValue 硬编码到MyModelViewB 中时,两个视图都没有得到newValue 既不是MyModelViewB 也没有更新MyModelViewA this.rows 可观察到的。

那时我不确定我是否从上面提到的链接中得到了正确的答案才能让它工作。

编辑

我已经添加到我的模块包代码的顶部

var postbox = new ko.subscribable();

如下代码

(function($) { $(function() {
    window.postbox = new ko.subscribable();
    });
});

在尝试声明可订阅时抛出错误

无法读取未定义的属性“订阅”

然后在 MyModalViewA 的模块中添加了 PFX 答案的简化版本:

    postbox.subscribe(function(newValue) {
            self.myTest(newValue);

            console.log('New value: ' + newValue);
        }, null, "NewRowAvailable"
    );

并在MyModalViewB 的模块中添加MyModelViewB.findUsers

var newRow = "testing123";
postbox.notifySubscribers(newRow, "NewRowAvailable");

当我调试该代码时,它显示postbox 被定义为Object {NewValueAvailable: },但notifySubscribers 没有更新可订阅。

想法?

【问题讨论】:

  • 如果父模型负责生成子模型,我会在构造函数中传递对 rows 数组的引用。
  • @user3297291 当我尝试在子模型中访问this.rows 时,它说是undefinied

标签: javascript arrays knockout.js observable model-view


【解决方案1】:

确保postboxinstance 是在两个视图模型之间共享的同一个实例,并且notifySubscriberssubcribe 方法遵循以下签名。

notifySubscribers(eventData, eventName); 

subscribe(function(eventData) { ... }, null, eventName);

您可以在下面找到您要实现的目标的简化版本。
这里只传递了 1 个搜索结果,但它也可能更多,例如。一个数组。

var postbox = ko.observable();

function MyModalViewA()
{
    var _self = this;
    _self.rows = ko.observableArray([
        { label: "foo" },
        { label: "bar" }    
        ]);
    
    postbox.subscribe(function(newValue) {         
          _self.rows.push(newValue);
      }, null, "PFX.NewRowAvailable"
      );
};

function MyModalViewB()
{
    var _self = this;
    
    _self.search = function() {
    
        var newRow = { "label" : "baz" };
        postbox.notifySubscribers(newRow, "PFX.NewRowAvailable");      
    };
};

var vma = new MyModalViewA();
ko.applyBindings(vma, $("#vma").get(0));

var vmb = new MyModalViewB();
ko.applyBindings(vmb, $("#vmb").get(0));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<div id="vma">
    <h3>ViewModel A</h3>
    <ol data-bind="foreach: rows">
        <li data-bind="text: label"></li>
    </ol>
</div>

<hr />

<div id="vmb">    
    <h3>ViewModel B</h3>
    <button data-bind="click: search">search</button>
</div>

【讨论】:

  • 看起来很简单,但是当我尝试在我的代码中实现 postbox.notifySubscribers 时遇到问题,其中每个 ModalView 都是 webpack 中的单独模块。每个模块(和 ModalView)都将 postbox 视为可观察的,但没有得到更新。此外,notifySubscribers() 上的 KnockoutJS 文档也很弱。想法?
  • 我将邮箱作为自定义命名空间上的全局单例:(function($) { $(function() { window.PFX.postbox = new ko.subscribable(); }); } )(jQuery, window.PFX = window.PFX || {})
  • 我已根据您的回答用附加代码更新了我的问题,以便更好地阐明当前状态。
  • 您的视图模型中的postbox 是否与window.postbox 相同?
  • 我认为是这样 - 否则它会抛出 postbox 未定义。代码中没有其他postbox 声明。
猜你喜欢
  • 2013-12-16
  • 1970-01-01
  • 2012-04-20
  • 2012-07-16
  • 2012-10-01
  • 1970-01-01
  • 2017-02-19
  • 2017-11-25
  • 2016-12-26
相关资源
最近更新 更多