使用ko.toJSON调试主文件中的组件昏死

时间:2017-04-02 11:10:45

标签: javascript knockout.js components

我将我的观点(html)和我的viewModel(js)注册为淘汰组件。在我的主文件(index.html)中,我对组件进行数据绑定以显示不同的视图。此时,当我想使用ko.toJSON($ data,null,2)快速调试html中的viewModel时,我需要在我要调试的everey html文件中为ko.toJSON添加data-bindin。我想有一个更通用的方法来做这个,就像数据绑定ko.toJSON只在主文件(index-html)中传递viewModel / $数据?它。

//index.html
<body>

//here I want a generic way to debug my app like:
// <div data-bind="?">

    <div id="page" data-bind="component: {name: viewModel}"></div>
</body>

// components
ko.components.register('home', ko_home.init );
ko.components.register('import', ko_import.init );

//view
<main>
    <h1>home</h1>
     <div data-bind="text: greeting"></div>

// here I put the binding for debug in every view. It should be removed and //placed in the index.html
<pre data-bind="text: ko.toJson($data, null,2)"></pre>
</main>

//viewModel
const fs = require('fs');
const template = fs.readFileSync(__dirname + '/home.html', 'utf8');

function Home() {
    this.greeting = ko.observable('Hello');
}

exports.init = { viewModel: Home, template: template };

1 个答案:

答案 0 :(得分:0)

我想说包含debug元素的最简单方法是在注册组件时用它包装模板。

由于您已经拥有一个包含vm和模板的init对象,因此您可以在注册之前重新分配template属性以添加<pre> html字符串。

例如:

var appendDebugPre = function(htmlString) {
  var pre = document.createElement("pre");
  pre.setAttribute(
    "data-bind", 
    "html: ko.toJS($data, null, 2)"
  );
  
  // Might be better to create a documentFragment,
  // but for debug purposes, this might be enough
  return htmlString + pre.outerHTML;
};

// Regular register:
var c = messageEditor();

ko.components.register(c.name, c.init);

// Register a debug version:
ko.components.register("debug-" + c.name, 
  Object.assign({}, c.init, {
    template: appendDebugPre(c.init.template) // Here, we wrap the template
  }));


ko.applyBindings({});


// Utils:
// From knockout docs, an example component:
function messageEditor() {
  return {
    name: 'message-editor',
    init: {
      viewModel: function(params) {
        this.text = ko.observable(params && params.initialText || '');
      },
      template: 'Message: <input data-bind="value: text" /> ' +
        '(length: <span data-bind="text: text().length"></span>)'
    }
  };
};

// Stub
ko.toJS = function(vm) {
  return JSON.stringify(
    Object.keys(vm).reduce(function(res, k) {
      res[k] = ko.unwrap(vm[k]);
      return res;
    }, {}), 
    null,
    2
  );
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<div data-bind="component: 'message-editor'"></div>
<div data-bind="component: 'debug-message-editor'"></div>