5

わかりました、これは私を夢中にさせています...ノックアウトでhtmlバインディングを作成する正しい方法を理解できないようで、Twitterのブートストラップ要素をうまく操作します。

私は、次のHTMLを持っています:

<li><a href="#"><i class="icon-user"></i> Enable/Disable User</a></li>

この行は、実際には ul にある他の li の一部ですが、簡単にするために必要な部分だけを示しています。

ご覧のとおり、アイコン クラスからもわかるように、ここでも Twitter ブートストラップを使用しています。

メニューをレンダリングすると、タグが正しく表示され、すべてがブートストラップ スタイルで適切にレンダリングされ、すべてが優れています。

ここで、これを変更して、メニュー オプションが常に同じことを言うのではなく、ビュー モデルに応じて変更するようにします。

私のビュー モデルでは、次のようなビュー モデルで knockout.js を使用しています。

function UserListViewModel()
{
  var self = this;
  self.ListItems = ko.observableArray([]);

  self.LoadListData = function()
  {
    self.ListItems([]);
    $.getJSON('/api/getusers',null,function(results)
    {
      self.ListItems(results);
    }
  }
} 

「LoadListData」関数を使用してロードされたときの観察可能な配列は完全に機能し、Json で API から返されたレコードの配列を ListItems にロードします。各レコードは次のようになります。

{"recordid": 1, "loginname": "joe", "fullname": "joe person", "isallowedlogin": 1}

これは 1 つのレコードにすぎません。複数のレコードがあり、すべてデータベースのユーザー テーブルから取得されます。

この質問で興味深いプロパティは「isallowedlogin」プロパティです。

現在、ノックアウト テンプレート バインディングを使用して、このユーザー リストをドキュメント内のテーブルにバインドしています。

<tbody data-bind="template: { name: 'UserListItemTemplate', foreach: ListItems, as: 'ListItem' }">
</tbody>

そして、この質問の冒頭で示した LI タグは、そのテンプレートの一部です...

<script type="text/html" id="UserListItemTemplate">
  <tr data-bind="css: { success: loginallowed == 1, error: loginallowed == 0}">
    <td data-bind="text: recordid">xx</td>
    <td>
      <li><a href="#"><i class="icon-user"></i> Enable/Disable User</a></li>
    </td>
  </tr>
</script>

繰り返しになりますが、他の LI タグやアンカーなどがあります。この質問に必要なものだけを示しています。

ここまでは順調ですね...

すべてのユーザーが含まれるテーブルと、各行の最後にあるリンクを取得します。データをロードすると、すべてのバインディングがうまく機能し、許可されたログイン ステータスに応じて、行の css が緑または赤に変わります。 .

前述したように、アンカー タグのテキストを動的に変更して、

IF isallowedlogin = 1 の場合、取得します

<li><a href="#"><i class="icon-user"></i> Disable User</a></li>

それ以外の場合はレンダリングされます IF isallowedlogin = 0 の場合、取得します

    <li><a href="#"><i class="icon-user"></i> Enable User</a></li>

レンダリングされます。すべて非常に単純なもの、またはそう思いました。

テキストバインディングを使用する場合

data-bind="text: 'Disable User'"

または私のモデルでcomputedObservable / observableを使用したテキストバインディング..

data-bind="text: someComputedObservable()"

動作しますが、アイコンが失われます

HTML バインディングを使用する場合:

data-bind="html: '<i class="..."></i> Disable User'"

または私のモデルでcomputedObservable / observableを使用したhtmlバインディング..

data-bind="html: '<i class="..."></i> ' + someComputedObservable()"

< や %22 などを使用して文字列を組み立てて特殊文字をエンコードしようとしても、解析エラーやあらゆる種類の狂気について不平を言うノックアウトが発生します。

私の 3 回目の試みは、計算されたオブザーバブルを使用して、関数内で直接 HTML 文字列を作成することでした。

function UserListViewModel()
{
  var self = this;
  self.ListItems = ko.observableArray([]);

  self.GetListItemText = ko.computedObservable(function(ListItem)
  {
    if(ListItem.isloginallowed == 1) {
      return '<i class="icon-user"></i> Disable User';
    }
    else {
      return '<i class="icon-user"></i> Enable User';
    }
  });
} 

それから私はそれをバインドしようとしました:

data-bind="html: $parent.GetListItemText"

計算されたオブザーバブルに何も渡すことができないことがわかっただけなので、テーブルにリンクをレンダリングしているときに現在どの行のデータにいるのかわからなかったため、テキストがどうあるべきかを判断できません。

それで、最後に、ビューモデルの外で通常の関数を試してみましょう...

現在のオブジェクトをそれに渡すことができ、問題がないことはわかっています...

違う...

私が定義した場合:

function GetMenuEnabledDisabledOptionText(ListItem)
{
    if(ListItem.isloginallowed == 1) {
      return '<i class="icon-user"></i> Disable User';
    }
    else {
      return '<i class="icon-user"></i> Enable User';
    }
}

ビューモデルの外で、次のようにバインドします。

<li><a href="#" data-bind="html: GetMenuEnabledDisabledOptionText">xx</a></li>

メニューをレンダリングすると、アンカー タグに挿入される実際のオプション テキストは、JS ファイルに入力された関数定義です!!!

マッドメニュー!

私ができるようにしたいのは、アイコンを殺さずにテキストを更新することだけです。HTML を含む文字列を手動で作成する必要がある場合は、そうする必要がありますが、ノックアウトを取得して、関連するものだけを計算して更新したいと思います。可能であれば少し。

やるべきことはとても簡単なことですが、JavaScript のやり方では A** の苦痛になります...

何か案は?

更新 1

返されたテキストではなく関数定義全体を取得していた理由がわかりました。ちょっとしたツールだったようです。関数名の後に括弧を追加していないことに気づいていなかったので、

<li><a href="#" data-bind="html: GetMenuEnabledDisabledOptionText">xx</a></li>

になるはずだった

<li><a href="#" data-bind="html: GetMenuEnabledDisabledOptionText()">xx</a></li>

平手打ち....

ただし、テキストの更新に関するアイデアをまだ探しています...

4

1 に答える 1

6

数時間イライラした後、わかりました.....

結局のところ、私がしなければならなかったのは、テンプレートバインディングで計算されたオブザーバブルに $data を渡すことだけでした...

したがって、次のビューモデルがあるとします。

function UserListViewModel()
{
  var self = this;
  self.ListItems = ko.observableArray([]);

  self.GetListItemText = ko.computedObservable(function(ListItem)
  {
    if(ListItem.isloginallowed == 1) {
      return '<i class="icon-user"></i> Disable User';
    }
    else {
      return '<i class="icon-user"></i> Enable User';
    }
  });
} 

以前は「ListItem」が常にnullであるため、問題が発生していました....

ただし、Binding を次のように定義した場合:

data-bind="html: GetListItemText($data)"

次にListItemにアクセスしようとすると、魔法のように、ループしている各行のプロパティがあります:-)

うーん、教訓は……。

于 2013-04-25T22:43:47.540 に答える