1

私が達成しようとしているもの: 1 つのテキスト入力フィールド (名前)、いくつかのオプション (タイプと列) を持つ 2 つの選択フィールドを持つフォームと、タイトルが名前に設定されたウィジェットを作成する送信ボタン、データ型がに設定されたフォームタイプと列 - ページ内の位置です。

この場合の Type には、ビューで定義されたいくつかの異なるオプションがあります。これはうまく機能するので、今のところ、それを機能させる方法については説明しません。

今のところ、3つの列を持つページがあり、それぞれが独自のobservableArrayであるため、次のようになります。

self.col0 = ko.observableArray([]);
self.col0.id = 'col0'

col1 と col2 も同様です。ここでの私の目標は、選択フィールドがこれらの配列を指すようにすることです。少なくともそれは私がする必要があると思うことです。

DOM の Name 値と Type 値を確認する createWidget 関数があります (ここで間違っている場合は訂正してください。これが KnockOut で作成する最初のものです)。そのデータから新しい Widget を作成します。それで:

var Widget = function(name, type) {
  var self  = this;
  self.name = name;
  self.type = type;
}; 

var ViewModel = function() {
  var self = this;
  self.newWidgetName = ko.observable();
  self.newType       = ko.observable();

// Unrelated code in between

self.createWidget = function(target) {
  newName = self.newWidgetName();
  newType = self.newType();
  widget  = new Widget(newName, newType);
  target.unshift(widget)
  self.newWidgetName("");
};

DOM の入力/選択要素

input.widget-name type="text" placeholder="wName" data-bind="value: newWidgetName"

select data-bind="value: newType"
  option value="calendar" Calendar
  option value="article"  Article
  option value="document" Document

select.colPick data-bind="value: colPick"
  option value="col0" Column 1
  option value="col1" Column 2
  option value="col2" Column 3

そして、createWidget 関数のクリック ハンドラー - 次のように:

a.btn.create-widget data-bind="click: function(){ createWidget(col0); }"

シャザム、効きます!

ただし、これは新しいウィジェットを最初の列 (col0) にのみ出力し、列選択フィールドの値を考慮せず、新しいウィジェットを正しい列にシフト解除します。多くの試行錯誤の末に発生するエラーは、次のようになります。

1) 「undefined のメソッド unshift を呼び出すことはできません」

2) 「キャッチされていない TypeError: オブジェクト関数 observable() .... メソッド 'unshift' がありません

現時点では、コードは上記の例のようになっています。決して理想的ではありませんが、さまざまな列がノックアウトソート可能に接続されているため、この機能を破棄する必要がある場合でも大したことではありません。ユーザーは引き続きウィジェットを col0 から col2 に、またはその逆に移動できます。

誰かが私を正しい方向に向けるリソースを持っている場合、または彼らの答えを知っている場合は、遠慮なく共有してください!

万歳、カス。

編集: Tyrsius へのフォローアップの質問

あなたが提供したコードを使用すると、選択ボックスで 3 つの列が機能するようになりましたが、ウィジェットをビューに出力する際に​​少し苦労しています。

以前のコードでは、ビューは次のようになりました。

<div class="cols">
  <div class="col col-25">
    <ul data-bind="sortable: { template: 'widgetTmpl', data: col0, afterMove: $root.widgetData }">
    </ul>
  </div>
  <div class="col col-50">
    <ul data-bind="sortable: { template: 'widgetTmpl', data: col1, afterMove: $root.widgetData }">
    </ul>
  </div>
  <div class="col col-25">
    <ul data-bind="sortable: { template: 'widgetTmpl', data: col2, afterMove: $root.widgetData }">
    </ul>
  </div>
</div>

私が今取り組んでいるのはこれです:

<div data-bind="foreach: columns">
  <div data-bind="foreach: items" class="col">
    <ul data-bind="sortable: { template: 'widgetTmpl', data: columns, afterMove: $root.widgetData }"></ul>
  </div>
</div>

私の最初の質問は、その時は考えていなかったことに気づいたので、飛ばしてください。

質問 2: フォームで選択した列にこれらのウィジェットをバインドするにはどうすればよいですか? 私はこれをしますか?

<ul data-bind="sortable: { template: 'widgetTmpl', data: entryColumn, afterMove: $root.widgetData }"></ul>

それとも私は離れていますか?:)

4

1 に答える 1

3

列のアイテムのコレクションをタイプとして保持します。これは次のようになります。

var Column = function(header) {
    this.header = ko.observable(header);
    this.items = ko.observableArray([]);
};

トリックは、select列をビューモデルの列のリストに直接バインドすることです。

<select data-bind="options: columns, optionsText: 'header', value: entryColumn"

ここで起こっていることはcolumn、ドロップダウンで選択された実際のオブジェクトがentryColumnプロパティに保存されるということです。itemsアイテムへの参照があるため、後でアイテムをそのリストに直接入れることができます。これにより、ロジックを変更せずに任意の数の列をサポートすることもできます。

追加コードは単純なままです。

self.columns = ko.observableArray(columns);

self.entryName = ko.observable('');
self.entryType = ko.observable('');
self.entryColumn = ko.observable('');
self.types = ko.observableArray(['Small', 'Medium', 'Large']);

self.addWidget = function() {
        var widget = new Widget(self.entryName(), self.entryType());
        //Here is where we can directly add to the selected columns item list
        self.entryColumn().items.push(widget);
        self.resetForm();
    };

これがこれらを示すフィドルです。


フォローアップの質問

あなたは近いですが、データはそうではありitemsませんEntryColumn

<div data-bind="foreach: columns">
    <div data-bind="sortable: { template: 'widgetTmpl', data: items}" class="column">        
    </div>
</div>

<script type="text/html" id="widgetTmpl">
    <p data-bind="text: name() + ' - ' + type()"></p>
</script>

これが更新された fiddleです。

于 2013-03-14T16:03:48.873 に答える