2013-09-11 6 views
2

В настоящее время я использую jQuery, Twitter Bootstrap и CanJS для своего веб-приложения. Я пытаюсь реализовать маршрутизацию с помощью CanJS. Я использую вкладку Bootstrap, и когда я нажимаю на вкладку, она должна приводить #tabSearch, #tabUser или #tabPermissions, но хеш возвращается с пустой строкой. Что я делаю неправильно?Location.hash возвращает пустую строку

I'm, используя это, чтобы изменить вкладки:

 TabControl = can.Control.extend({}, { 
     init: function (element, options) { 
     element.find('a[href="' + options.defaultTab + '"]').tab('show'); 
     this.userSearch = null; 
     this.userForm = null; 
    } 
    , 'a[data-toggle="tab"] show': function (e) { 
     this.options.tabChangeCallback(e); 
    } 
}); 

    UserTab = new TabControl('#tabctrlUser', { 
     defaultTab: '#tabSearch', 
     tabChangeCallback: function (e) { 

     if (e.context.hash == '#tabSearch') {     
      if (!this.userSearch) { 
       this.userSearch = new FormUserQuery('#tabSearch', {}); 
      } 
     } else if (e.context.hash == '#tabUser') { 
      if (!this.userForm) { 
       this.userForm = new FormUser('#tabUser', {}); 
      } 
      this.userForm.renderView(currentUser); 
     } else if (e.context.hash == '#tabPermissions') {     
      new FormPermissions('#tabPermissions', {}); 

     } 
    } 
}); 

Ниже представлен HTML часть:

<ul id="tabctrlUser" class="nav nav-tabs"> 
    <li><a href="#tabSearch" data-toggle="tab">Pesquisar</a></li> 
    <li><a href="#tabUser" data-toggle="tab">Cadastrar/Alterar</a></li> 
    <li><a href="#tabPermissions" data-toggle="tab">Acessos</a></li> 
</ul> 
<div class="tab-content"> 
    <div class="tab-pane" id="tabSearch"></div> 
    <div class="tab-pane" id="tabUser"></div> 
    <div class="tab-pane" id="tabPermissions"></div> 
</div> 

ответ

2

Вы должны использовать can.route или can.Control.Route, как вы делаете это сложно взглянуть на this question Также есть 2 goodarticles о маршрутизации

взгляда на этой gist

http://jsfiddle.net/Z9Cv5/2/light/

var HistoryTabs = can.Control({ 
    init: function(el) { 

    // hide all tabs 
    var tab = this.tab; 
    this.element.children('li').each(function() { 
     tab($(this)).hide(); 
    }); 

    // activate the first tab 
    var active = can.route.attr(this.options.attr); 
    this.activate(active); 
    }, 
    "{can.route} {attr}" : function(route, ev, newVal, oldVal){ 
    this.activate(newVal, oldVal) 
    }, 
    // helper function finds the tab for a given li 
    tab: function(li) { 
    return $(li.find('a').attr('href')); 
    }, 
    // helper function finds li for a given id 
    button : function(id){ 
    // if nothing is active, activate the first 
    return id ? this.element.find("a[href=#"+id+"]").parent() : 
       this.element.children('li:first'); 
    }, 
    // activates 
    activate: function(active, oldActive){ 
    // deactivate the old active 
    var oldButton = this.button(oldActive).removeClass('active'); 
    this.tab(oldButton).hide(); 
    // activate new 
    var newButton = this.button(active).addClass('active'); 
    this.tab(newButton).show(); 
    }, 
    "li click" : function(el, ev){ 
    // prevent the default setting 
    ev.preventDefault(); 
    // update the route data 
    can.route.attr(this.options.attr, this.tab(el)[0].id) 
    } 
}); 

// configure routes 
can.route(":component",{ 
    component: "model", 
    person: "mihael" 
}); 

can.route(":component/:person",{ 
    component: "model", 
    person: "mihael" 
}); 

// adds the controller to the element 
new HistoryTabs('#components',{attr: 'component'}); 
new HistoryTabs('#people',{attr: 'person'}); 
1

Я не знаком с CanJS, но это может иметь что-то, чтобы сделать этот якорь щелчок случается до навигация и местонахождение.hash установлен после. Например. если (в качестве теста) вы определяете ссылку как

<a href="#tabSearch" onclick="tabChangeCallback()">Pesquisar</a> 

И в простой ванили JS попробовать

function tabChangeCallback() { 
    alert(location.hash) 
} 

Он будет отображаться пустой.

Но если вы пытаетесь что-то вроде

function tabChangeCallback() { 
    setTimeout(function() { 
     alert(location.hash) 
    }, 100) 
} 

Это будет отображать хэш. Поэтому в вашем случае либо установите ваш код для выполнения в таймаут после основного события, либо (и я думаю, что это лучший вариант) вместо хеша, вы должны прочитать атрибут связанного элемента, вызвавшего событие, href.

Update Равнина JS Приведенный ниже пример показывает, как получить значение хеш-функции без тайм-аута:

function tabChangeCallback(e) { 

    var elem = e ? e.target : event.srcElement 

    alert(elem.getAttribute("href")) 
} 
+0

Что вы имеете в виду чтения HREF atrribute элемента анкера? – Glund

+0

В коде обработчика событий вы должны иметь доступ к элементу, вызвавшему событие. Обычно это нечто вроде 'e.target' или' e.srcElement '. Когда вы нажимаете '

+0

P.S. Обновлен мой ответ, чтобы проиллюстрировать подход –

Смежные вопросы