避免将document.getElementById与Backbone.js一起使用

时间:2014-11-24 14:22:47

标签: javascript backbone.js

我正在使用Backbone.js创建一个应用程序,但我是Backbone.js的新手。我需要更改HTML元素的样式属性。有没有办法使用Backbone.js中的东西来改变HTML元素的样式?

在index.html中我放了隐藏的段落:

<input type="text" id="name" placeholder="Enter name">
<p id="error_msg_name1" style="display: none;">
    Please, enter the name of the configuration.
</p>

当有人试图在模型中保存空的“名称”时,应显示此段落,我这样处理:

var nameValue = document.getElementById("name").value;
if (nameValue == '') {
    document.getElementById("error_msg_name1").style.display = 'inline';
}

我的导师告诉我,我不应该使用document.getElementById,我应该使用Backbone.js中的内容。我用Google搜索了好几天,但我没有找到任何帮助。

这是我的模特:

var Configuration = Backbone.Model.extend({

  defaults: function() {
      return {
          name: '',
          description: '',
          version: ''
      };
  }

});

这是视图:

var ConfigurationView = Backbone.View.extend({

    events: {
        'click #ok': 'createConf',
        'click #cancel': 'cancelConf',
        'click #preview': 'showJSON',
        'click #readFile': 'readFile'
    },

    readFile: function() {
        var files = document.getElementById('fileInput').files;

        if (!files.length) {
            alert('Please select a file!');
            return;
        }

        var file = files[0];
        var reader = new FileReader();

        reader.onloadend = function(evt) {
            if (evt.target.readyState == FileReader.DONE) {
                var fileContent = evt.target.result;
                document.getElementById('previewFile').textContent = fileContent;
                importedConfiguration = new Configuration(JSON.parse(fileContent));

                $('<div class="col-sm-offset-2 col-sm-10">\
                        <button type="button" class="btn btn-default btn-sm" id="update">Update</button>').appendTo('#for_button');
            }
        };

        reader.readAsBinaryString(file);
    },

    remove: function() {
        $(this.el).empty().detach();
        return this;
    },

    cancelConf: function() {
        this.render();
    },

    createConf: function() {

        document.getElementById("error_msg_name1").style.display = 'none';
        document.getElementById("error_msg_name2").style.display = 'none';
        document.getElementById("error_msg_description").style.display = 'none';
        document.getElementById("error_msg_version").style.display = 'none';

        var nameRegex = /^[A-Za-z]+$/;

        var nameValue = document.getElementById("name").value;
        var descriptionValue = document.getElementById("description").value;
        var versionValue = document.getElementById("version").value;

        if (descriptionValue != ''  && versionValue != '' && nameRegex.test(nameValue)) {
            configuration.set({name: nameValue, description: descriptionValue, version: versionValue});

            document.getElementById("for_preview_JSON").innerHTML = JSON.stringify(configuration);
            document.getElementById("for_preview_JSON").disabled = true;

            var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(configuration));
            $('<a href="data:' + data + '" download="data.json">download JSON</a>').appendTo('#for_download_link_JSON');

            document.getElementById("ok").disabled = true;
            document.getElementById("preview").disabled = true;
            document.getElementById("name").disabled = true;
            document.getElementById("description").disabled = true;
            document.getElementById("version").disabled = true;
        }
        else {
            if (nameValue == '') {
                document.getElementById("error_msg_name1").style.display = 'inline';
            }else if(!nameRegex.test(nameValue)) {
                document.getElementById("error_msg_name2").style.display = 'inline';
            }

            if (descriptionValue == '') {
                document.getElementById("error_msg_description").style.display = 'inline';
            }
            if (versionValue == '') {
                document.getElementById("error_msg_version").style.display = 'inline';
            }
        }
    },

    showJSON: function() {
        var preview_conf = new Configuration({
            name: document.getElementById("name").value, 
            description: document.getElementById("description").value, 
            version: document.getElementById("version").value
        });
        document.getElementById("for_preview_JSON").innerHTML = JSON.stringify(preview_conf);
        document.getElementById("for_preview_JSON").disabled = true;
    },

    initialize: function(options){
        this.template = options.template;
    },

    render: function(){
        var content = $(this.template).html();
        $(this.el).html(content);
        return this;
    }
});

2 个答案:

答案 0 :(得分:3)

在更改任何源代码之前,我想您需要了解Bakcbone.View的工作原理以及您需要如何以Backbone方式访问/查询DOM。

每次在示例中初始化Backbone.View并提及模板时,您都可以使用this.$el访问模板,这是jQuery元素并引用您的模板。

对于您的情况,您正在对DOM进行大量不必要的查询。而不是只使用this.$el来查找/修改模板的HTML。

示例:

var MyView = Backbone.View.extend({
    template: _.template($('#your-template-id').html()),
    events: {
        "click .something": "doOtherThing"
    }, 
    doOtherThing: function (e) {
        // this.$el.find() same as this.$() within view.
        $myEl = this.$('.innerElement'); // cache element when you need to do a lot of manipulations   
        $myEl.addClass('changed'); // 
        $myEl.toggleClass('opened') // and so on...
    }
    render: function () {
        var template = this.template(this.model.toJSON);
        this.$el.append(template);
    } 
});

var myView = new MyView();
myView.render();

要记住的一些规则:

<强> 1。不要查询全局

如果您需要在视图中添加/删除/修改HTML元素,请始终使用this.$el来访问视图。

<强> 2。缓存常用元素

 $myEl = this.$el.find('.innerElement'); 
 $myEl.addClass('changed');  
 $myEl.toggleClass('opened');
....

第3。 Bakcbone.View this.$el.find()内与this.$()

相同

答案 1 :(得分:0)

我会在你的文件中添加这样的东西

// before code
events: {
  // other events
  'click #save': 'saveEntry'
}
, saveEntry: function() {
  if( this.checkEmptyName() ) {
    // do other saving stuff
  }
}
, checkEmptyName: function() {
  var name = this.$el.find( '#name' ).val();
  if( name.length === 0 ) {
    this.$el.find( '#error_msg_name1' ).show();
    return false;
  }
  return true;
}
// everything else