【问题标题】:Looping through array in Knockout and binding to HTML在 Knockout 中循环遍历数组并绑定到 HTML
【发布时间】:2019-12-11 12:06:58
【问题描述】:

我对 Knockout 不是很熟悉,但现在作为速成课程学习它。我的任务是遍历这个 JSON 对象并将某些节点放入带有结果的 div 中。它基本上是一个视频卡显示器,每种信息都会显示某些位 - 类型、信息、缩略图和标题。然后,我必须在单击缩略图时加载视频播放器,但那是稍后。对于像我这样的新手,任何帮助将不胜感激。它只是回来未定义。

这是我的 JSON 对象。我的方向正确吗?

var json= {
    "available": true,
    "screens": [{
            "id": "s01",
            "type": "Selector",
            "config": {
                "views": [{
                    "id": "sintel",
                    "type": "selectorItem",
                    "thumbnail": "http://test-cdn.selectablemedia.com/test/a/sintel/assets/img/thumb_sintel.png",
                    "title": "Sintel",
                    "description": "Small video. HTML5, native controls, start poster. Bottom, right social. Video + grid",
                    "info": "00:51"
                }, {
                    "id": "bbb",
                    "type": "selectorItem",
                    "thumbnail": "http://test-cdn.selectablemedia.com/test/a/bbb/assets/img/thumb_bbb.png",
                    "title": "Big Buck Bunny",
                    "description": "Large video. HTML5, custom controls, social hover. Video + replay",
                    "info": "00:33"
                }, {
                    "id": "walle",
                    "type": "selectorItem",
                    "thumbnail": "http://test-cdn.selectablemedia.com/test/a/walle/assets/img/thumb_walle.png",
                    "title": "WALL-E",
                    "description": "Small video. Youtube, custom controls. Left social. Video + carousel.",
                    "info": "02:30"
               }]
            }
        },
        {
            "id": "sintel",
            "type": "BrandWrapper",
            "config": {
                "views": [{
                    "id": "sintelBranding",
                    "type": "fullBranding",
                    "url": "sintel_single.png"
                }, {
                    "id": "sintelPlayer",
                    "type": "smPlayerIframe",
                    "files": [{
                            "type": "mp4",
                            "codecs": "h264,aac",
                            "url": "http://test-cdn.selectablemedia.com/test/a/sintel/assets/video/sintel_trailer-1080p.mp4"
                        },
                        {
                            "type": "mp4",
                            "codecs": "avc1.42E01E,mp4a.40.2",
                            "url": "http://test-cdn.selectablemedia.com/test/a/sintel/assets/video/sintel_trailer-1080p.mp4"
                        },
                        {
                            "type": "ogv",
                            "codecs": "theora,vorbis",
                            "url": "http://test-cdn.selectablemedia.com/test/a/sintel/assets/video/sintel_trailer-1080p.ogv"
                        },
                        {
                            "type": "flv",
                            "codecs": "h264,aac",
                            "url": "http://test-cdn.selectablemedia.com/test/a/sintel/assets/video/sintel_trailer-1080p.flv"
                        }
                    ]
                }, {
                    "id": "sintelLeftClickArea",
                    "type": "brandClickArea",
                    "area": "leftTower",
                    "clickParams": {
                        "value": "https://durian.blender.org/"
                    }
                }, {
                    "id": "sintelHeaderClickArea",
                    "type": "brandClickArea",
                    "area": "header",
                    "clickParams": {
                        "value": "https://durian.blender.org/about/"
                    }
                }, {
                    "id": "sintelFooterClickArea",
                    "type": "brandClickArea",
                    "area": "footer",
                    "clickParams": {
                        "value": "https://durian.blender.org/gallery/"
                    }
                }]
            }
        },
        {
            "id": "bbb",
            "type": "BrandWrapper",
            "config": {
                "views": [{
                    "id": "bbbBrandingHeader",
                    "type": "header",
                    "url": "bbb_header.png"
                }, {
                    "id": "bbbBrandingLeft",
                    "type": "leftTower",
                    "url": "bbb_tower_left.png"
                }, {
                    "id": "bbbBrandingRight",
                    "type": "rightTower",
                    "url": "bbb_tower_right.png"
                }, {
                    "id": "bbbBrandingFooter",
                    "type": "footer",
                    "url": "bbb_footer.png"
                }, {
                    "id": "bbbPlayer",
                    "type": "smPlayerIframe",
                    "files": [{
                            "type": "mp4",
                            "codecs": "h264,aac",
                            "url": "http://test-cdn.selectablemedia.com/test/a/bbb/assets/video/bbb_trailer_1080p.mp4"
                        },
                        {
                            "type": "mp4",
                            "codecs": "avc1.42E01E,mp4a.40.2",
                            "url": "http://test-cdn.selectablemedia.com/test/a/bbb/assets/video/bbb_trailer_1080p.mp4"
                        },
                        {
                            "type": "ogv",
                            "codecs": "theora,vorbis",
                            "url": "http://test-cdn.selectablemedia.com/test/a/bbb/assets/video/bbb_trailer_1080p.ogv"
                        },
                        {
                            "type": "flv",
                            "codecs": "h264,aac",
                            "url": "http://test-cdn.selectablemedia.com/test/a/bbb/assets/video/bbb_trailer_1080p.flv"
                        }
                    ]
                }, {
                    "id": "bbbLeftClickArea",
                    "type": "brandClickArea",
                    "area": "leftTower",
                    "clickParams": {
                        "value": "https://peach.blender.org/"
                    }
                }, {
                    "id": "bbbHeaderClickArea",
                    "type": "brandClickArea",
                    "area": "header",
                    "clickParams": {
                        "value": "https://peach.blender.org/"
                    }
                }, {
                    "id": "bbbRightClickArea",
                    "type": "brandClickArea",
                    "area": "rightTower",
                    "clickParams": {
                        "value": "https://peach.blender.org/"
                    }
                }, {
                    "id": "bbbFooterClickArea",
                    "type": "brandClickArea",
                    "area": "footer",
                    "clickParams": {
                        "value": "https://peach.blender.org/"
                    }
                }]
            }
        },
        {
            "id": "walle",
            "type": "BrandWrapper",
            "config": {
                "assetPath": "http://test-cdn.selectablemedia.com/test/a/walle/assets/img/",
                "sizeTemplate": "smallVideo",
                "views": [{
                    "id": "walleBranding",
                    "type": "fullBranding",
                    "url": "walle_single.png"
                }, {
                    "id": "wallePlayer",
                    "type": "smPlayerIframe",
                    "files": [{
                            "type": "mp4",
                            "codecs": "h264,aac",
                            "url": "http://test-cdn.selectablemedia.com/test/a/walle/assets/video/wall-e-trailer-3_9_1280x544.mp4"
                        },
                        {
                            "type": "mp4",
                            "codecs": "avc1.42E01E,mp4a.40.2",
                            "url": "http://test-cdn.selectablemedia.com/test/a/walle/assets/video/wall-e-trailer-3_9_1280x544.mp4"
                        },
                        {
                            "type": "ogv",
                            "codecs": "theora,vorbis",
                            "url": "http://test-cdn.selectablemedia.com/test/a/walle/assets/video/wall-e-trailer-3_9_1280x544.ogv"
                        },
                        {
                            "type": "flv",
                            "codecs": "h264,aac",
                            "url": "http://test-cdn.selectablemedia.com/test/a/walle/assets/video/wall-e-trailer-3_9_1280x544.flv"
                        }
                    ]
                }, {
                    "id": "wallLeftClickArea",
                    "type": "brandClickArea",
                    "area": "leftTower",
                    "clickParams": {
                        "value": "http://movies.disney.com/wall-e/"
                    }
                }, {
                    "id": "walleHeaderClickArea",
                    "type": "brandClickArea",
                    "area": "header",
                    "clickParams": {
                        "value": "http://movies.disney.com/wall-e/"
                    }
                }, {
                    "id": "walleRightClickArea",
                    "type": "brandClickArea",
                    "area": "rightTower",
                    "clickParams": {
                        "value": "http://movies.disney.com/wall-e/"
                    }
                }, {
                    "id": "walleFooterClickArea",
                    "type": "brandClickArea",
                    "area": "footer",
                    "clickParams": {
                        "value": "http://movies.disney.com/wall-e/"
                    }
                }]
            }
        }
    ]
}

以下是我尝试编写的一些淘汰代码,但它返回未定义。我知道这很愚蠢:(。只是想注销,以便我可以开始执行此任务

var PageViewModel = function (json) {
var self = this;
self.screens = ko.observableArray([]);
self.addSection = function (jsonobj) {
    console.log("jsonobj", jsonobj);
    self.screens.push(new my.VideoSection(jsonobj));
    console.log(self.screens());
}
for (var i = 0; i < json.screens.length; i++) {
    self.addSection(json.screens[i]);

}
};

return {
  pageViewModel: pageViewModel
}

我的html开始循环

  <div data-bind="foreach: screens">
     <div class="container">
      <div class="row">    
        <div class="col-md-6 ">
            <div class="card">
                <div class="card-image">
                    <div  class="embed-responsive embed-responsive-16by9">

                </div>
                 </div><!-- card image -->

                <div class="card-content">
                    <span class="card-title" data-bind="text:title"> </span> 
                    <span class="card-title" data-bind="text:thumbnail"> </span>
                    <span class="card-title" data-bind="text:info"> </span>                      
                  </div><!-- card content -->
                </div>
            </div>
        </div>
      </div>

       <div class="row">    
        <div class="col-md-6 ">
            <div class="card">
               <div class="card-image">
                  <div  class="embed-responsive embed-responsive-16by9">

                </div>
                </div><!-- card image -->

                <div class="card-content">
                    <span class="card-title" data-bind="text:title"> </span> 
                    <span class="card-title" data-bind="text:thumbnail"> </span>  
                    <span class="card-title" data-bind="text:info"> </span> 

                 </div><!-- card content -->
              </div>
            </div>
        </div>
      </div>
    </div>

【问题讨论】:

    标签: jquery knockout.js


    【解决方案1】:

    您似乎走在正确的轨道上。需要注意的几点:

    • 您没有发布my.VideoSection 构造函数的代码;
    • 您正确地循环了screens,但是screen 对象有一个config 属性,其中有一个views 数组,您还需要循环该数组。您可以使用foreach: config.views 或使用with 绑定将绑定上下文切换到父元素上的配置属性。

    所以基本上是这样的:

    <div data-bind="foreach: screens">
        <div class="container" data-bind="with: config">
            <div class="row" data-bind="foreach: views">    
                <div class="col-md-6">
                    <div class="card">
                        <img class="card-img-top" data-bind="attr: { src: thumbnail }">
                        <div class="card-body">
                            <h5 class="card-title" data-bind="text:title"> </h5> 
                            <p class="card-text" data-bind="text:info"> </p>                      
                        </div><!-- card content -->
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    小提琴:https://jsfiddle.net/thebluenile/9yvpfr7n/

    【讨论】:

    • 非常感谢@brother woodrow。它正在渲染,但奇怪的是在浏览器中出现了这个错误。未捕获的引用错误:无法处理绑定“foreach:函数(){返回屏幕}”消息:无法处理绑定“with:函数(){返回配置}”消息:无法处理绑定“foreach:函数(){返回视图}" 消息:无法处理绑定 "attr: function(){return { src:thumbnail} }" 消息:缩略图未定义
    • 所以我现在明白了原因。 JSON 对象还有更多内容,并且在某种程度上循环失败了。现在我迷路了哈哈。任何其他提示将不胜感激,并感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    • 2012-03-10
    • 2019-04-19
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多