【问题标题】:Calling Knockout.js viewModel function from JQuery onclick从 JQuery onclick 调用 Knockout.js viewModel 函数
【发布时间】:2012-12-07 02:50:57
【问题描述】:

对knockout.js 很陌生,我是一名C#'er,但我的新工作除了后端之外还涉及更多的前端,所以终于解决了这个问题。

无论如何,我遇到过(我认为是)一个不寻常的场景,我想从 JQuery 中的点击事件中调用 viewModel 方法;也许这很常见,但我不太明白:: 希望有人能提供帮助!

我的 viewModel 文件中有一个简单的函数: //add to playlist
self.addToPlaylist = function (video) {
self.addedVideos.push(video);
};

我正在使用一个名为 fancybox 的 Jquery 库将许多图像加载到轮播中,因此我已绑定到名为 videos 的 observableArray

<div id="carousel" data-bind="foreach: videos">
             <!-- Left and right buttons -->
            <input id="left-button" type="button" value="" />
            <input id="right-button" type="button" value="" />
                <!-- All images with class of "cloudcarousel" will be turned into carousel items -->
                <!-- You can place links around these images -->
                <a class="fancybox-iframe" href="#" rel="group">
                    <img class="cloudcarousel" width="160" height="121" alt="test" data-bind="attr: {src: videoThumbnail, url: videoUrl, id: videoId, title: videoTitle, caption: videoCaption}"
                        onclick="previewVideo($(this).attr('url'), $(this).attr('caption'));CreateAddVideoClipButton($(this).attr('id'));" />                     
                </a>
            </div>    

这是该 div 的完整 html。理想情况下,我会 click: $parent.addToVideos 在 data-bind 属性中,但因为我正在侦听的点击在这个阶段不会发生,所以我必须呈现一个添加按钮。 想法是点击打开fancybox中的预览,然后用户可以关闭窗口,或者点击添加将此视频添加到数组中。

好的,希望这对人们有意义...

在我的 Jquery 方法 CreateAddVideoClipButton 中,我有:

var userModel = new VideosViewModel();
var text = "<a href='#' data-bind='click: userModel.addToPlaylist'>Add Video</a>";

这就是我卡住的地方。 在这个阶段我需要知道如何允许点击,在我的viewModel中调用addToPlaylist方法

如果您需要更多信息来说明这一点,请告诉我。


编辑:发布代码

视图模型:

function VideosViewModel() {
    var self = this;

    //Array of videos
    self.videos = ko.observableArray([
        { videoTitle: "Video Title",
        videoId: "1",
        videoThumbnail: "images/image.png",
        videoAlt: "Alt text",
        videoUrl: "videos/video.mp4",
        videoCaption: 'video caption text' },

    ]);

    //Array of added videos
    self.addedVideos = ko.observableArray([]);

    //add to playlist
    self.addToPlaylist = function (video) {
        self.addedVideos.push(video);
        alert("Added to playlist");
    };

    //remove from playlist
    self.removeFromPlaylist = function (video) {
        self.addedVideos.remove(video);
    };
}
ko.applyBindings(new VideosViewModel());

HTML:

<div id="carousel" data-bind="foreach: videos">
             <!-- Left and right buttons -->
            <input id="left-button" type="button" value="" />
            <input id="right-button" type="button" value="" />
                <!-- All images with class of "cloudcarousel" will be turned into carousel items -->
                <!-- You can place links around these images -->
                <a class="fancybox-iframe" href="#" rel="group">
                    <img class="cloudcarousel" width="160" height="121" alt="test" data-bind="attr: {src: videoThumbnail, url: videoUrl, id: videoId, title: videoTitle, caption: videoCaption}",
                        onclick="previewVideo($(this).attr('url'), $(this).attr('caption'));CreateAddVideoClipButton($(this).attr('id'));" />                     
                </a>
            </div>  

添加视频剪辑功能

function CreateAddVideoClipButton(selectedVideoId) {
    var theElement = document.getElementById(selectedVideoId);
    var videoUrl = theElement.getAttribute('url');
    var videoThumb = theElement.getAttribute('src');
    var videoTitle = theElement.getAttribute('title');
    var videoId = theElement.getAttribute('id');
    selectedImageId = videoId;
    //var userModel = new VideosViewModel();
    var text = "<input type=\"button\" id=\"addButton\" class=\"addButton\" value=\"Add Video Clip\" onclick=\"addVideo(" + "'" + videoUrl + "'" + ", " + "'" + videoThumb + "'" + "," + "'" + videoTitle + "'" + "," + "'" + videoId + "'" + ");\" />";
    //var text = "<a href=\"#\" onclick=" + userModel.addToPlaylist() + "\">Add Video</a>";
    currentimageid = text;
    currentSelectedImageId = selectedImageId;
    hidePlayer();
}

【问题讨论】:

  • VideosViewModel是有addToPlaylist()功能的型号吗?你能发布你的模型的骨架代码来澄清一下吗?
  • 你是什么意思“但是因为我正在监听的点击在这个阶段没有发生”?
  • @Anmzeo - 发布的代码将解释:
  • 谢谢!我去看看

标签: jquery knockout.js fancybox-2


【解决方案1】:

据我了解,您希望不引人注意地处理事件。

如果你看这里很简单:

http://knockoutjs.com/documentation/unobtrusive-event-handling.html

【讨论】:

    【解决方案2】:

    我相信您的问题是您正在混合 onClick 属性和 Knockout 处理程序,而您应该只使用 Knockout 处理程序。使用这些处理程序将处理所有样板代码,例如您在 addVideoClipButton 中添加的代码。

    例子:

     <button data-bind="visible: showAddButton, click: $parent.addToPlaylist">Add to playlist</button>
    

    我已将您的代码复制到 fiddle,看看如何通过使用 Knockout 处理程序来简化您的代码。

    【讨论】:

    • 由于时间限制,我们最终使用纯 jQuery 完成了很多工作,但在假期期间,我打算尝试从头开始重新编写应用程序。我会尝试你的建议,如果有帮助,我会标记为答案。谢谢大家的建议,祝大家圣诞快乐!
    【解决方案3】:

    我会做这样的事情

    var VideosViewModel = {
        addToPlaylist : function () {
            alert("Added to playlist");
        }
    };
    
    ko.applyBindings(VideosViewModel);
    
    $('#testBtn').click(function(){
        VideosViewModel.addToPlaylist();            
    });
    ​
    

    http://jsfiddle.net/VyUT4/4/

    【讨论】:

      【解决方案4】:

      你可以这样做 -

      ViewModel -

      var searchViewModel = function () {
          var self = this;
      
          self.search = function (param) {
          //do something
          };
      
      }
      

      HTML -

      <button data-bind="click: function () { Search() }" class="" id="searchBtn">Search</button>
      

      jquery -

      function Search() {
      // paramvalue = 1; 
      viewModel.search(paramvalue);                  
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-12
        • 2013-08-26
        • 1970-01-01
        相关资源
        最近更新 更多