2012-08-13 74 views
0

我有以下标记:的Html绑定到动态内容

<div id="metro-hub"> 
    <h1 id="hub-title" data-bind="text: hubTitle" class="hub-title">@Model.HubTitle</h1> 
    <div id="hubWrapper" data-root-url="/Root" data-bind="html: currentHub"></div> 
</div> 

我使用KnockoutJS绑定一个viewModel JavaScript对象的视图。我还创建了一个自定义绑定,将导航连接到服务器上的站点地图。下面是从我这么远一些片段:

var MetroPageViewModel = function() { 
    var self = this; 

    self.currentHub = ko.observable(); 
    self.viewPortData = ko.observable(); 
    self.hubTitle = ko.observable(); 

    self.renderHub = function (rootUrl) { 
     console.log(rootUrl); 
     $.ajax({ 
      url: '/Base/NewHub', 
      type: 'get', 
      data: { 
       url: rootUrl 
      }, 
      success: function (data) { 
       if (data) { 
        var wrappedData = $(data); 
        var newHubContent = wrappedData.find('ul'); 
        var title = wrappedData.find('input.metro-hub-title').val(); 
        self.hubTitle(title); 
        self.currentHub(newHubContent); //THIS IS THE LINE THAT DOES NOT WORK 
       } 
      } 
     }); 
    }; 

    self.initialize = function() { 
     var url = $('#hubWrapper').data('root-url'); 
     self.renderHub(url); 
    }; 
}; 

$(function() { 
    var viewModel = new MetroPageViewModel(); 
    ko.applyBindings(viewModel); 
    viewModel.initialize(); 
}); 

和这里的自定义绑定使用Sammy.js库根据网址哈希做路由:

ko.bindingHandlers.metroHub = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var menuItems = $(element).find('li'); 
     Sammy(function() { 
      var $this = this; 
      menuItems.each(function (index, elem) { 
       $this.get('#/' + $(elem).data('link-name'), function() { 
        var numChildren = $(elem).data('num-children'); 
        if (numChildren > 0) { 
         var rootUrl = (elem).data('source-url'); 
         viewModel.renderHub(rootUrl); 
        } else { 
         var dataSource = $(elem).data('source-url'); 
         $.ajax({ 
          url: dataSource, 
          type: 'get', 
          success: function (data) { 
           if (data) { 
            viewModel.viewPortData(data); 
           } 
          } 
         }); 
        } 
       }); 
      }); 
      var firstItem = menuItems[0]; 
      var itemRoute = '#/' + $(firstItem).data('link-name'); 
      $this.get('', function() { this.app.runRoute('get', itemRoute) }); 
     }).run(); 
    } 
}; 

数据是从服务器返回如下:

<div><ul class="metro-menu" data-bind="metroHub: true"><li data-link-name="Home" data-num-children="0" data-source-url="/Navigation/Item1"><a href="#/Home">Home</a></li><li data-link-name="Products" data-num-children="2" data-source-url="/Navigation/Item2"><a href="#/Products">Products</a></li><li data-link-name="Services" data-num-children="0" data-source-url="/Navigation/Item3"><a href="#/Services">Services</a></li></ul> 
<input class="metro-hub-title" type="hidden" value="this is a hub title"></input> 
<input class="hasParentNode" type="hidden" value="False"></input> 
</div> 

UPDATE:

现在的问题是,一旦renderHub()方法中的AJAX回调返回,自定义绑定update回调没有被触发。我是否需要调用某种方法来强制绑定或任何东西?

有什么想法?

回答

0

也许你应该更新绑定上的父容器的更新绑定,因为该控件正在更新。

我认为更新不会触发是因为应该对更新做出响应的旧div完全被新html替换。

如果我通过在绑定中使用与更新相同的代码创建init函数,可以快速检查。

+0

不,没有工作。我已经尝试过,但没有运气。 – Kassem 2012-08-14 18:12:48