2014-02-20 6 views
7

Ich habe die grundlegende Durandal HTML Vorlage verwendet, aber ich habe Bootstrap mit Zurb Foundation ersetzt. Alles funktioniert gut, außer dem Problem, dass ich keine Mods, Drop-Downs oder irgendetwas, das Foundation initialisiert, öffnen kann. Im Allgemeinen würde man die folgende in dem Körper Ihrer Webseite platzieren, dies zu tun:Durandal und Zurb-Stiftung, wo sollte ich Fundament initialisieren?

<script> 
    $(document).foundation(); 
</script> 

hat ich versucht, dies Ort in den Index.html, Shell.html und sogar zufällig in dem Viewmodel und Ansicht. Außerdem habe ich versucht, es von JS aus in der main.js und das Viewmodel selbst in der activate-Sektion zu initialisieren. Nichts davon hat funktioniert. Die (hoffentlich sehr temporäre) Abhilfe, die ich gefunden habe, ist tatsächlich init Foundation mein Javascript bilden, wenn eine Schaltfläche des Modal zu öffnen:

$(document).foundation(); 
$("#myModal").foundation("reveal", "open"); 

Wohin gehe ich falsch?

Meine main.js Referenz:

(function() { 
    requirejs.config({ 
    paths: { 
     text: "../lib/require/text", 
     durandal: "../lib/durandal/js", 
     plugins: "../lib/durandal/js/plugins", 
     transitions: "../lib/durandal/js/transitions", 
     knockout: "../lib/knockout/knockout-2.3.0", 
     jquery: "../lib/jquery/jquery-1.9.1", 
     foundation: "../lib/foundation/js/foundation/foundation", 
     "foundation.abide": "../lib/foundation/js/foundation/foundation.abide", 
     "foundation.accordion": "../lib/foundation/js/foundation/foundation.accordion", 
     "foundation.alert": "../lib/foundation/js/foundation/foundation.alert", 
     "foundation.clearing": "../lib/foundation/js/foundation/foundation.clearing", 
     "foundation.dropdown": "../lib/foundation/js/foundation/foundation.dropdown", 
     "foundation.interchange": "../lib/foundation/js/foundation/foundation.interchange", 
     "foundation.joyride": "../lib/foundation/js/foundation/foundation.joyride", 
     "foundation.magellan": "../lib/foundation/js/foundation/foundation.magellan", 
     "foundation.offcanvas": "../lib/foundation/js/foundation/foundation.offcanvas", 
     "foundation.orbit": "../lib/foundation/js/foundation/foundation.orbit", 
     "foundation.reveal": "../lib/foundation/js/foundation/foundation.reveal", 
     "foundation.tab": "../lib/foundation/js/foundation/foundation.tab", 
     "foundation.tooltip": "../lib/foundation/js/foundation/foundation.tooltip", 
     "foundation.topbar": "../lib/foundation/js/foundation/foundation.topbar" 
    }, 
    shim: { 
     jquery: { 
     exports: "jQuery" 
     }, 
     foundation: { 
     deps: ["jquery"] 
     }, 
     "foundation.abide": { 
     deps: ["foundation"] 
     }, 
     "foundation.accordion": { 
     deps: ["foundation"] 
     }, 
     "foundation.alert": { 
     deps: ["foundation"] 
     }, 
     "foundation.clearing": { 
     deps: ["foundation"] 
     }, 
     "foundation.dropdown": { 
     deps: ["foundation"] 
     }, 
     "foundation.interchange": { 
     deps: ["foundation"] 
     }, 
     "foundation.joyride": { 
     deps: ["foundation"] 
     }, 
     "foundation.magellan": { 
     deps: ["foundation"] 
     }, 
     "foundation.offcanvas": { 
     deps: ["foundation"] 
     }, 
     "foundation.orbit": { 
     deps: ["foundation"] 
     }, 
     "foundation.reveal": { 
     deps: ["foundation"] 
     }, 
     "foundation.tab": { 
     deps: ["foundation"] 
     }, 
     "foundation.tooltip": { 
     deps: ["foundation"] 
     }, 
     "foundation.topbar": { 
     deps: ["foundation"] 
     } 
    } 
    }); 

    define(["durandal/system", "durandal/app", "durandal/viewLocator", "foundation"], function(system, app, viewLocator, foundation) { 
    system.debug(true); 
    app.title = "Durandal Starter Kit"; 
    app.configurePlugins({ 
     router: true, 
     dialog: true, 
     widget: true 
    }); 
    app.start().then(function() { 
     viewLocator.useConvention(); 
     app.setRoot("viewmodels/shell", "entrance"); 
    }); 
    }); 

}).call(this); 

shell.html:

<div> 
    <nav class="top-bar hide-for-small"> 
     <ul class="title-area"> 
      <!-- Title Area --> 
      <li class="name"> 
       <h4 style="color: white">KRS Template</h4> 
      </li> 
      <!-- Remove the class "menu-icon" to get rid of menu icon. Take out "Menu" to just have icon alone --> 
      <li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li> 
     </ul> 
     <div class="top-bar-section"> 
      <!-- Right Nav Section --> 
      <ul class="right" data-bind="foreach: router.navigationModel"> 
       <li data-bind="css: { active: isActive }"> 
        <a data-bind="attr: { href: hash }, html: title"></a> 
       </li> 
      </ul> 
     </div> 
    </nav> 
    <div class="container-fluid page-host" data-bind="router: { transition: 'entrance', cacheViews: true }"></div> 
</div> 

shell.js:

(function() { 

    define(["plugins/router", "durandal/app", "foundation"], function(router, app, foundation) { 
    return { 
     router: router, 
     activate: function() { 
     router.map([ 
      { 
      route: "", 
      title: "Welcome", 
      moduleId: "viewmodels/welcome", 
      nav: true 
      }, { 
      route: "List", 
      moduleId: "viewmodels/ListOfItems", 
      nav: true 
      } 
     ]).buildNavigationModel(); 
     return router.activate(); 
     } 
    }; 
    }); 

}).call(this); 

Wo das eigentliche Problem liegt: ListOfItems.html:

<section> 
    <div> 
     <h2 data-bind="text: displayName" style="text-align: center"></h2> 
     <div class="row"> 
      <div class="small-12 column"> 
       <div data-bind="foreach: items"> 
        <div class="panel"> 
         <div class="row"> 
          <div class="small-6 column"> 
           <b>Number: <span data-bind="text: NumberA"></span></b> 
           <br /> 
           <b>Number B: <span data-bind="text: NumberB"></span></b> 
           <br /> 

          </div> 
          <div class="small-6 column"> 
           <b>Text A: <span data-bind="text: StringA"></span></b> 
           <br /> 
           <b>Text B: <span data-bind="text: StringB"></span></b> 
           <br /> 
           <b>Text C: <span data-bind="text: StringC"></span></b> 
           <br /> 
          </div> 
          <div class="row"> 
           <div class="small-12 column"> 
            <a class="button" data-bind="click: function() { $parent.openModal(this); }">Open Modal</a> 
           </div> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     </div> 
     <div id="myModal" class="reveal-modal" data-reveal> 
      <h2>Edit Item</h2> 
      <p class="lead">Please alter the item</p> 
      <input id="Stepper" type="number" data-bind="value: ModalNumberA" /> 
      <input id="Number1" type="number" data-bind="value: ModalNumberB" /> 
      <input type="text" placeholder="Scope name" data-bind="value: ModalStringA" /> 
      <input type="text" placeholder="Scope name" data-bind="value: ModalStringB" /> 
      <input type="text" placeholder="Scope name" data-bind="value: ModalStringC" /> 
      <a class="small button" data-bind="click: saveModalChanges">Save</a> 
      <a class="small button" data-bind="click: closeModal">Close</a> 
      <a class="close-reveal-modal">&#215;</a> 
     </div> 
    </div> 
</section> 

ListOfItems.js (erzeugt von Coffeescript):

(function() { 
    var _this = this; 

    define(["durandal/app", "knockout", "krs", "jquery", "foundation.reveal", "foundation.dropdown"], function(app, ko, krs, $, reveal, dropdown) { 
    return { 
     displayName: "List of Items", 
     items: ko.observableArray([]), 
     result: ko.observable(), 
     ModalNumberA: ko.observable(), 
     ModalNumberB: ko.observable(), 
     ModalStringA: ko.observable(), 
     ModalStringB: ko.observable(), 
     ModalStringC: ko.observable(), 
     ItemBeingEdited: ko.observable(), 
     activate: function() { 
     var _this = this; 
     return callTheWebApi("http://localhost:54129/api/mocked/GetMockedViewModelList", "GET", "", function(result) { 
      console.log(result); 
      _this.items(result); 
     }); 
     }, 
     openModal: function(item) { 
     this.ItemBeingEdited(item); 
     this.ModalNumberA(item.NumberA); 
     this.ModalNumberB(item.NumberB); 
     this.ModalStringA(item.StringA); 
     this.ModalStringB(item.StringB); 
     this.ModalStringC(item.StringC); 
     $(document).foundation(); 
     return $("#myModal").foundation("reveal", "open"); 
     }, 
     saveModalChanges: function() { 
     var itemBeingEdited, 
      _this = this; 
     itemBeingEdited = new Object(); 
     itemBeingEdited.NumberA = this.ModalNumberA(); 
     itemBeingEdited.NumberB = this.ModalNumberB(); 
     itemBeingEdited.StringA = this.ModalStringA(); 
     itemBeingEdited.StringB = this.ModalStringB(); 
     itemBeingEdited.StringC = this.ModalStringC(); 
     return callTheWebApi("http://localhost:54129/api/mocked/SaveMockedViewModel", "GET", "{'model':" + JSON.stringify(itemBeingEdited) + "}", function(success) { 
      var templist; 
      if (success) { 
      _this.items()[_this.items().indexOf(_this.ItemBeingEdited())] = itemBeingEdited; 
      templist = _this.items(); 
      _this.items(null); 
      _this.items(templist); 
      return $("#myModal").foundation("reveal", "close"); 
      } 
     }); 
     }, 
     closeModal: function() { 
     return $("#myModal").foundation("reveal", "close"); 
     } 
    }; 
    }); 

}).call(this); 

Wenn jemand darauf hinweisen könnte, wo ich falsch mache ich würde es wirklich schätzen.

+0

Gibt es einen Grund, dass Sie Ihre View-Modell-Definition-Aufrufe in einer selbstausführenden Funktion umbrechen? –

+0

Hallo, ich entwickle in CoffeeScript, ich denke, es ist nur ein Nebeneffekt der Kompilierung. Aber TY, ich werde deine Antwort unten testen und Feedback geben. –

+0

Hast du das jemals herausgefunden? – lux

Antwort

0

Ich glaube, dass Skript-Tags aus Ansichten von Durandal entfernt werden, so dass das wahrscheinlich ist, warum das nicht funktioniert.

Nicht sicher über die Struktur oder Art Ihres Projekts, aber wenn Ihre durandal App über eine Webseite ausgeliefert wird, können Sie Foundation auf der Webseite initialisieren.

Alternativ könnten Sie es in der CompletionComplete oder angehängte Methoden Ihres Shell-View-Modells initialisieren.

1

Sie können in Erwägung ziehen, benutzerdefinierte Knockout-Bindungen für Foundation zu erstellen. Andernfalls werden Sie in Ihren Viewmodels mit DOM-Referenzen enden, was in den meisten Fällen ein Anti-Pattern für Durandal ist. Wenn Sie mit benutzerdefinierten Knockout-Bindungen nicht vertraut sind, können Sie sie unter http://knockoutjs.com/documentation/custom-bindings.html lesen. Wenn Sie Hilfe bei benutzerdefinierten Bindungen benötigen, kehren Sie hierher zurück, und ich werde Ihnen gerne weiterhelfen.

Wenn ich mich erinnere, ist Foundation() ein Schwergewicht Initialisierung Aufruf. Sie müssen es nur einmal tun. Eine einfache benutzerdefinierte Bindung in Ihrer Shell.html würde die Initialisierung trivialisieren - den Durandal/Knockout-Weg.

+0

Hallo, Danke für die Antwort, ich habe die benutzerdefinierte Bindung hinzugefügt und ich lief in meinem Main.js, es funktioniert, wenn ich das Observable in meinem View- und Viewmodel habe. Es schlägt immer noch fehl, wenn ich versuche, es höher in die Kette oder in den Index zu schieben. Es ist noch nicht ganz perfekt, aber so nah und effizient wie ich denke, ich kann Geld verdienen. –

2

Wenn Foundation im Block darunter initialisiert wird verlangt, dass alle Objekte, die es Methoden modals mögen bindet, dropdowns usw. innerhalb des DOM sein.Dies bedeutet, dass Sie Folgendes tun können, um sicherzustellen, dass die meisten Funktionen der Foundation vorhanden sind.

Initialisierungscode

$(document).foundation(); 

es einige KISS geben und halten es einfach, dass man das zu jedem ‚Ansichtsmodell‘ attached oder compositionComplete Rückruf innerhalb der aufgeführten here hinzufügen können. Dies stellt sicher, dass alle Elemente innerhalb des DOM sind, wenn Foundation initialisiert ist.

Beispiel

define(function(require){ 
    var backend = require('backend'); 

    return { 
    customers:ko.observableArray([]), 
    activate:function(){ 
     // This runs as soon as the viewModel is loaded 
    } 
    attached:function(){ 
     // This runs as soon as the view is full rendered 
     $(document).foundation(); 
    } 
    }; 
}); 

Zusätzlich verwende ich Mikro-Templat für modal (die nicht in dem DOM während Foundation Initialisierung oft sind) und ein Trick, den ich gefunden habe, ist Grundlage gegen das Objekt selbst zu initialisieren.

Beispiel

$('#dynamicElement').foundation(); 

Dies ist für Dinge, die funktioniert data attributes wie modals verwenden und ermöglicht es Ihnen Foundation Methoden gegen diese Objekte zu laufen.


In Bezug auf die Stiftung mit KnockOut.js Erwähnungen in anderen Antworten. Ich habe mir das angeschaut, wie ich es liebe Foundation und KnockOut ist mein Brot und Butter, aber die beiden funktionieren einfach nicht gut zusammen. Am Ende schreibst du die gesamte Foundation um mit KO zu arbeiten und ich persönlich habe keine Zeit dafür, würde es aber gerne sehen.

Wenn Sie wirklich brauchen, das ansprechende Design und alle Glocken und Pfeifen der Stiftung integriert in Durandal Sie wirklich brauchen Bootstrap zu verwenden, da es diese Funktionen in einem kompatiblen Weise bietet.

+0

HI Matt, danke für die Antwort. Ich benutzte Bootstrap mit Durandal, ich generierte den HTML-Code von PineGrow und platzierte ihn in der Ansicht und es funktionierte wie ein Zauber. Jetzt mache ich das gleiche mit Bootstrap und eckigen. –

+0

Das ist wahrscheinlich das Beste, was zu dieser Zeit zu tun ist. Ich hoffe, dass Foundation es irgendwann in Durandal schaffen wird, aber da Rob dem Angular2.0-Team beitritt, ist es nicht wahrscheinlich. – MattSizzle

Verwandte Themen