Durandal和Zurb基金会,我应该在哪里初始化基础?

时间:2014-02-20 17:29:57

标签: requirejs zurb-foundation durandal

我一直在使用基本的Durandal HTML模板,但我已经用Zurb Foundation替换了Bootstrap。一切都运作良好,除了我无法打开任何模态,下拉或任何需要基础初始化的问题。通常会将以下内容放在您网页的正文中:

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

我试图将其放在Index.htmlShell.html中,甚至在视图模型和视图中随机放置。此外,我尝试在main.js中使用JS启动它,并在activate部分中使用viewmodel本身。这些都没有奏效。我发现的(希望是非常临时的)解决方法是实际初始化我的javascript基础,当点击按钮打开模态时:

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

我哪里错了?

我的main.js供参考:

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

实际问题在于: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(从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);

如果有人能指出我哪里出错了,我会非常感激。

3 个答案:

答案 0 :(得分:2)

在下面的块中初始化Foundation时,它要求所有绑定方法的对象(如modalsdropdowns等)都在DOM中。这意味着您可以执行以下操作以确保存在大多数基础功能。

初始化代码

$(document).foundation();

给它一些KISS并保持简单,您可以将其添加到列出的attachedcompositionComplete回调中的每个'viewModel'here。这将确保在Foundation初始化时所有元素都在DOM中。

示例

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

此外,我使用微模板进行模态化(在基础初始化期间通常不在DOM中),我发现的一个技巧是初始化对象本身的基础。

示例

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

这适用于使用data attributes的内容,例如模态,并允许您针对这些对象运行Foundation方法。


关于KnockOut.js的基金会在其他答案中提及。我已经调查了这一点,因为我喜欢FoundationKnockOut是我的面包和黄油,但这两者并不能很好地协同工作。最后你要重写所有的基金会与KO一起工作,而且我个人没有时间做这件事,但很想看到它发生。

如果您确实需要响应式设计以及将Durandal整合到基金会的所有花哨功能,您确实需要使用Bootstrap,因为它以兼容的方式提供这些功能。

答案 1 :(得分:1)

您可能需要考虑为Foundation创建自定义Knockout绑定。否则,你将在整个视图模型中使用DOM引用,在大多数情况下,这是Durandal的反模式。

如果您不熟悉自定义Knockout绑定,可以在http://knockoutjs.com/documentation/custom-bindings.html阅读它们。如果您需要有关自定义绑定的帮助,请返回此处,我将很乐意为您提供帮助。

如果我记得,foundation()是一个重量级的初始化调用。你只需要做一次。一个简单的自定义绑定放在你的shell.html上会使初始化变得无足轻重--Durandal / Knockout方式。

答案 2 :(得分:0)

我相信脚本标签会被durandal从视图中剥离出来,这可能就是为什么不能解决这个问题。

不确定项目的结构或性质,但如果您的durandal应用程序是通过网页提供的,则可以在网页中初始化基础。

或者,您可以在您的shell视图模型的compositionComplete或附加方法中初始化它。