【问题标题】:Can't properly load JSON into DOM because of this keyword由于此关键字,无法将 JSON 正确加载到 DOM
【发布时间】:2020-01-12 12:34:59
【问题描述】:

我正在尝试通过 javascript 模块化模式加载 JSON。 我想要 3 个人在 JSON 文件上,加载到 DOM 中。 我相信在将 this 绑定到 loadingData 函数后,它指向了错误的对象

这是我的代码

(function() {

    var people = {
        people: [],

        init: function() {
                this.cacheDom();
                this.bindEvents();
                this.render();
        },

        cacheDom: function () {
            this.$el = document.querySelector('#peopleModule');
            this.$button = this.$el.querySelector('button');
            this.$input = this.$el.querySelector('input');
            this.$ul = this.$el.querySelector('ul');
            this.template = this.$el.querySelector('#people-template').innerHTML;
        },

        bindEvents: function() {
            document.addEventListener('DOMContentLoaded', this.loadingData.bind(this));

        },

        render: function() {
            var data = {
                people: this.people
            };
            this.$ul.innerHTML = Mustache.render(this.template, data);
        },

        loadingData: function() {
            var xhr = new XMLHttpRequest(),
                url = 'data/data.json',
                _self = this,
                result;
            xhr.onreadystatechange = function() {
                if(this.readyState == 4 && this.status == 200) {
                    result = JSON.parse(this.responseText);
                    _self.people = result.people;
                }
            };
            xhr.open('GET', url, true);
            xhr.send();

        }
    };

    people.init();

})();

这是我的 JSON

{
    "people": [
        {
            "name" : "Cameron"
        },
        {
            "name" : "Alex"
        },
        {
            "name" : "Sara"
        }
    ]   
}

这是我的 HTML

<div id="peopleModule">
        <h1>People</h1>
        <div>
            <input type="text" placeholder="Name">
            <button id="addPerson">Add Person</button>          
        </div>
        <ul id="people">
            <script id="people-template" type="text/template">
                {{#people}}
                <li>
                    <span>{{name}}</span>
                    <del>X</del>
                </li>
                {{/people}}
            </script>
        </ul>
    </div>

【问题讨论】:

  • 因为您只是在调用您的函数,而不是使用new 从它们创建对象实例,this 并不代表这些实例。 people 不应该被声明为对象字面量,它应该被声明为 function People 然后你可以用 let peopleObj = new People() 来调用它。然后peopleObj 将引用已创建的对象实例,this 还将在运行代码中引用该实例。
  • 如果我删除 loadingData 对象并仅使用 people = ['1', '2', '3'] 之类的示例数据,如果我将所有其他函数作为回调函数运行,它也可以用于 loadingData从 JSON 加载数据,但我不喜欢回调解决方案
  • 当我在它执行的 loadingData 函数中添加一个警报时,为什么会这样说?
  • 我并不是说你的函数不会执行。我是说你调用你的函数的方式导致this 没有按照你想要的方式绑定。 this 用于构造函数(使用 new 关键字调用的函数)。

标签: javascript design-patterns module mustache


【解决方案1】:

我把 render() 函数放错地方了

this关键字无关

(function() {

    var people = {
        people: [],

        init: function() {
                this.cacheDom();
                this.bindEvents();
        },

        cacheDom: function () {
            this.$el = document.querySelector('#peopleModule');
            this.$button = this.$el.querySelector('button');
            this.$input = this.$el.querySelector('input');
            this.$ul = this.$el.querySelector('ul');
            this.template = this.$el.querySelector('#people-template').innerHTML;
        },

        bindEvents: function() {
            document.addEventListener('DOMContentLoaded', this.loadingData.bind(this));

        },

        render: function() {
            var data = {
                people: this.people
            };
            this.$ul.innerHTML = Mustache.render(this.template, data);
        },

        loadingData: function() {
            var xhr = new XMLHttpRequest(),
                url = 'data/data.json',
                _self = this,
                result;
            xhr.onreadystatechange = function() {
                if(this.readyState == 4 && this.status == 200) {
                    result = JSON.parse(this.responseText);
                    _self.people = result.people;
                    _self.render();
                }
            };
            xhr.open('GET', url, true);
            xhr.send();

        }
    };

    people.init();

})();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多