从JQuery onclick调用Knockout.js viewModel函数

时间:2012-12-19 17:19:30

标签: jquery knockout.js fancybox-2

对于knockout.js来说很新,我是一个C#'呃但是我的新工作除了后端之外还涉及了更多的前端,所以最终得到了这个。

无论如何,我遇到过(我认为)一个不寻常的场景,我想从JQuery中的click事件调用viewModel方法;也许这很常见,但我无法弄清楚::希望有人可以提供帮助!

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

我正在使用一个名为fancybox的Jquery库将一些图像加载到轮播中,所以我绑定了我的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。理想情况下,我会在数据绑定属性中点击:$ parent.addToVideos,但因为我正在侦听的点击不会发生在这个阶段我必须渲染一个添加按钮。 想法是点击打开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();
}

4 个答案:

答案 0 :(得分:2)

根据我的理解,你想要不引人注意地处理事件。

如果你看这里很简单:

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

答案 1 :(得分:2)

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

示例:

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

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

答案 2 :(得分:0)

我会做那样的事情

var VideosViewModel = {
    addToPlaylist : function () {
        alert("Added to playlist");
    }
};

ko.applyBindings(VideosViewModel);

$('#testBtn').click(function(){
    VideosViewModel.addToPlaylist();            
});
​

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

答案 3 :(得分:0)

你可以这样做 -

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);                  
}