【问题标题】:can't resolve knockout js with nested objects无法解决带有嵌套对象的淘汰赛js
【发布时间】:2012-09-07 06:39:42
【问题描述】:

我正在尝试学习 knockoutjs,但无法弄清楚孩子 observable 是如何工作的!我已经尝试阅读许多文章和许多问题,即使是在 SO 上,但可能在某处遗漏了一些东西。

我的 json 结构是(由 Rails json 渲染器生成):

专辑 -> 曲目 -> 元数据

Album
 -Track
  --Metadata
 -Track
  --Metadata
Album
 -Track     
  -- Metadata

等等

我的视图也是嵌套的。在一个页面中,每张专辑都位于一个 div 下,每首曲目都位于上述 div 中的表格行下。

我的视图和 JS 代码在 JS Fiddle 中。 http://jsfiddle.net/var56/

问题: 如果您在 JSFiddle 中看到该视图,您将看到我已标记 html 部分正在工作(专辑)和不工作(曲目)。初始视图正确渲染。当我在文本字段中更新专辑名称时,上面的 h2 正在正确更新。但是在轨道模板中,当我更新轨道标题时,它不会在下面的跨度中更新。

此外,我尝试在 chrome 控制台中导出数据。

ko.toJSON(viewModel)

或者, ko.mapping.toJSON(viewModel)

它给了我旧数据(也就是说,不返回更改的值)。

我还将添加/删除专辑和曲目,并希望 viewModel 和视图反映相同。

我在哪里遗漏了什么?


注意:实际 JSON 数据在这里:

[
  { "id":9,
    "image_path":null,
    "name":"Test Album",
    "price":null,
    "sort_order":null,
    "tracks":[
      { "file_name":"01._Ei_Mon_Joshonay.mp3",
        "file_path":"/media/tracks/1/01._Ei_Mon_Joshonay.mp3",
        "id":192,
        "length":null,
        "metadata":{
          "artist":"Aroti (MR present)",
          "composer":"",
          "created_at":"2012-09-10T11:33:42Z",
          "duration":211,
          "genre":"Other",
          "id":124,
          "lyrics":null,
          "title":"01. Ei Mon Joshonay.mp3",
          "track_id":192,
          "updated_at":"2012-09-10T11:33:54Z",
          "year":0
        },
        "price":null,
        "thumb":"/media/track_thumbs/1/thumb_192.jpg",
        "title":"01. Ei Mon Joshonay.mp3"
      },
      { "file_name":"03._Jare_Ure_Ja_Pakhi.mp3",
        "file_path":"/media/tracks/1/03._Jare_Ure_Ja_Pakhi.mp3",
        "id":193,
        "length":null,
        "metadata":{
          "artist":"MR present",
          "composer":"",
          "created_at":"2012-09-10T11:33:48Z",
          "duration":204,
          "genre":"lata",
          "id":125,
          "lyrics":null,
          "title":"03.Jare ure ja pakhi",
          "track_id":193,
          "updated_at":"2012-09-10T11:33:54Z",
          "year":0
        },
        "price":99.0,
        "thumb":null,
        "title":"03.Jare ure ja pakhi"
      }
    ]
  },
  { "id":11,
    "image_path":null,
    "name":"Album 2",
    "price":null,
    "sort_order":null,
    "tracks":[  ]
  }
]

更新:

我什么都做不了。现在我尝试创建一个可以模拟我面临的问题的 jsFiddle。

请查看http://jsfiddle.net/Bb538/3/

我现在也有一个映射对象(尽管在代码中你可能会看到它没有被引用,如果你愿意,你可以试试)。您将看到专辑名称正在正确更新。但是 Title 和 File Name 字段不会更新相邻的 span(绑定到同一个 observable)。

【问题讨论】:

    标签: ruby-on-rails-3 knockout.js knockout-mapping-plugin


    【解决方案1】:

    根据您的更新,问题不在于子对象不可观察,而在于您的输入字段上的 data-bind 属性用于跟踪信息。 “value”数据绑定不是“attr”数据绑定的子项。

    这是一个有效的 jsFiddle http://jsfiddle.net/Bb538/4/

    你有什么

    <input data-bind="attr: { name: 'albums[track_attributes][$index][id]', value: title}" id="" name="" type="text" value=""/>
    

    应该是什么

    <input data-bind="attr: { name: 'albums[track_attributes][$index][id]'}, value: title" id="" name="" type="text" value=""/>
    

    【讨论】:

    • 嗨,感谢您发现我犯的错误!现在我看到轨道标题正在相应地更新下面的跨度!但是,为什么 FileName 的工作方式不同?它没有更新跨度(&lt;span class='uneditable-input file_path' data-bind='text: file_name'&gt;&lt;/span&gt;
    • 抱歉,两个输入都出现同样的错误,我只在另一个 jsFiddle 上更改了一个。这是更新http://jsfiddle.net/Bb538/5/
    • 非常感谢!这真的解决了我遭受了大约 1 周的问题。顺便说一句,即使没有引用任何映射对象(fromJS 方法的第二个参数),它是如何正常工作的?
    【解决方案2】:

    我怀疑您的“跟踪”对象和属性没有被映射插件映射到可观察对象,这会阻止它们在值更改时通知视图,反之亦然。

    在此处查看我关于将嵌套 JSON 对象结构映射到代表性视图模型的问答: Map JSON data to Knockout observableArray with specific view model type

    一个关键的要点是映射对象用于指定映射插件如何映射和转换嵌套对象。

    以下是与您的专辑曲目方案相关的具体示例: http://jsfiddle.net/KodeKreachor/qRKtK/26/

    【讨论】:

    • 我尝试过类似的映射,但也没有成功。好的,我也会发布这个实现。感谢您的意见
    • 你好,我无法正确理解上述链接中的实现!现在我尝试了一种手动制作可观察对象的方法。请检查为什么这也不起作用(它的行为与之前完全相同:只有专辑有效,但它的子节点无效)。 jsfiddle.net/Tmj9X
    • 查看我更新的答案,有一个特定的小提琴使用带有模板绑定的淘汰赛映射插件来呈现您的专辑曲目场景。
    猜你喜欢
    • 2015-01-04
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    相关资源
    最近更新 更多