6

問題: ウィジェットのダッシュボードを作成しようとしています。各ウィジェットのヘッダーには削除ボタンがあります。このボタンをクリックすると、対応するウィジェットが消える必要があります。

設計方法: 2 つのノックアウト コンポーネントがあります。

  1. my-widget-list: VO にはウィジェット オブジェクトの observableArray があります。
  2. my-widget: VO には、ウィジェット内に表示する詳細があります。

注: 簡単にするために、widget オブジェクトを数字だけに置き換えています。

ko.components.register('my-widget-list', {       
    viewModel : function(params) {
        var self = this;
        self.values = ko.observableArray([10,20,30,40,50]);

        self.deleteWidget = function(obj)
        {
            self.values.remove(obj);
        }
    },
    template: {element: 'my-widget-list-template'}
});

ko.components.register('my-widget', {
    viewModel : function(params) {        
        var self = this;        
        self.value = params.value;                        
    },
    template: {element: 'my-widget-template'}
});

ko.applyBindings({}); 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<my-widget-list></my-widget-list>

<script id="my-widget-list-template" type="text/html">
    <div data-bind="foreach:values">
        <my-widget params="value: $data"></my-widget><br>
    </div>
</script>

<script id="my-widget-template" type="text/html">
    <span data-bind="text: value"></span>
    <button data-bind="click: $parent.deleteWidget">Delete</button>
</script>

ここで、ボタンがクリックされたときにmy-widget-listの関数を呼び出したいと思います。deleteWidget

私は考えました

  • 親ビュー モデル参照を子に渡す
  • 子コンポーネントの params 属性で親関数をコールバックとして渡す

しかし、これを達成するための最良の方法は何かを専門家から知りたいです。

JsFiddle リンク

前もって感謝します

4

1 に答える 1

8

親をパラメーターとして子に渡すことができます。

ko.components.register('my-widget-list', {       
    viewModel : function(params) {
        var self = this;
        self.values = ko.observableArray([10,20,30,40,50]);

        self.deleteWidget = function(obj) {
            self.values.remove(obj);
        }
    },
    template: {element: 'my-widget-list-template'}
});

ko.components.register('my-widget', {
    viewModel : function(params) {        
        var self = this;        

        self.value = params.value;
        self.remove = function () {
            params.parent.deleteWidget(self.value);
        };
    },
    template: {element: 'my-widget-template'}
});

ko.applyBindings({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<my-widget-list></my-widget-list>

<script id="my-widget-list-template" type="text/html">
    <div data-bind="foreach:values">
        <my-widget params="value: $data, parent: $parent"></my-widget><br>
    </div>
</script>

<script id="my-widget-template" type="text/html">
    <span data-bind="text: value"></span>
    <button data-bind="click: remove">Delete</button>
</script>

しかし、不必要に子供を親に結合させるので、それが良い考えかどうかはわかりません。

親に「削除」ボタンを実装することをお勧めします。つまり<my-widget-list>、このようにして、ウィジェットリストが子を制御している間、ウィジェットリストなしで(または異なる構造のウィジェットに)ウィジェットを存在させることができます。

ウィンドウマネージャを比較してください: それらは同じように動作します. ウィンドウ マネージャーはフレームと最小化/最大化/閉じるボタンを描画しますが、ウィンドウの内容はそれぞれの子プロセスによって描画されます。そのロジックは、シナリオでも理にかなっています。


removeWidget親でコントロールを使用した代替実装:

ko.components.register('my-widget-list', {
    viewModel : function(params) {
        var self = this;

        self.values = ko.observableArray([10,20,30,40,50]);

        self.deleteWidget = function(obj) {
            self.values.remove(obj);
        }
    },
    template: {element: 'my-widget-list-template'}
});

ko.components.register('my-widget', {
    viewModel : function(params) {
        var self = this;

        self.value = params.value;
    },
    template: {element: 'my-widget-template'}
});

ko.applyBindings({});
.widget-container {
  position: relative;
  display: inline-block;
  padding: 10px 5px 5px 5px;
  margin: 0 5px 5px 0;
  border: 1px solid silver;
  border-radius: 2px;
  min-width: 40px;
}
.widget-buttons {
  position: absolute;
  top: 2px;
  right: 2px;
}
.widget-buttons > button {
  font-size: 2px;
  padding: 0;
  height: 15px;
  width: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<my-widget-list></my-widget-list>

<script id="my-widget-list-template" type="text/html">
    <div class="widget-list" data-bind="foreach:values">
        <div class="widget-container">
            <div class="widget-buttons">
                <button data-bind="click: $parent.deleteWidget">X</button>
            </div>
            <my-widget params="value: $data"></my-widget>
        </div>
    </div>
</script>

<script id="my-widget-template" type="text/html">
    <div class="widget">
        <span data-bind="text: value"></span>
    </div>
</script>

于 2015-07-09T08:52:31.043 に答える