【问题标题】:ember Uncaught TypeError: undefined is not a function when loading in storeember Uncaught TypeError: undefined is not a function when loading in store
【发布时间】:2014-06-28 19:54:56
【问题描述】:

我正在使用 ember 来显示从我的 golang 服务器接收到的数据。数据采用 JSON 格式。 所以我打开了一个 websocket 并尝试推送在商店中收到的消息,但我收到了这个错误: Uncaught TypeError: undefined is not a function

这是我的 app.js:

    App = Ember.Application.create({
  LOG_TRANSITIONS: true

})
/******************************* Post Template **************************************/

//Define a route for the template "post"
App.Router.map(function() {
  this.route("post", { path: "/post" });

});

//Post Model
App.Post = DS.Model.extend({
     name: DS.attr('string' ),
     number: DS.attr('string')
});


DS.SocketAdapterMixin = Ember.Mixin.create({
    uri: 'ws://localhost:8081/',
    init: function(){
        this.ws = new WebSocket(this.uri);

        // callbacks
        this.ws.onopen = function() {
          console.log('Connection established /all');
        };
        this.ws.onclone = function() {
          console.log('Connection closed /' + 'all');
        };
        this.ws.onmessage = function(data) {

         this.get('store').load(App.Post, data)
          console.log(data);

        };

        this._super();
    },

    initialize: function() {
        console.log('SocketAdapterMixin::initialize');
        this._super();
  }
});


DS.SocketAdapter = DS.RESTAdapter.extend(DS.SocketAdapterMixin, {
  init: function() {
    this._super();
    console.log('SocketAdapter');
  }

});

App.ApplicationAdapter = DS.SocketAdapter.extend({});

// Use the adapter in the store

App.Store = DS.Store.extend({
  revision: 13,
  adapter: DS.SocketAdapter.create({})
});

还有我的 index.html:

  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
    <title>Ember.js Example Application</title>

   <script src="js/libs/jquery-1.10.2.js"></script>
   <script src="js/libs/handlebars-1.1.2.js"></script>
   <script src="js/libs/ember-1.5.1.js"></script>
   <script src="js/libs/Ember_Data.js"></script>
   <script src="js/app.js"></script>
   <script src="js/router.js"></script>
 <!--  <script src="js/models/model.js"></script> -->

</head>
<body>
<h1>Bonjour </h1>


<script type="text/x-handlebars">
    Hello, {{firstName}} {{lastName}}<br/>

    <nav>
  {{#link-to 'post'}}Post{{/link-to}}
  </nav>

     <div>
      {{outlet}}
    </div>

</script>



<script type="text/x-handlebars" data-template-name="index">
    <h2>My Wrappers</h2>
    <ul>
    {{#each post in model}}
        <li>{{post.number}}</li>

    {{/each}}
    </ul>
  </script></p>


  <script type="text/x-handlebars" data-template-name="post">
     <h2>My Post</h2>
    <ul>
        <li> Zied</li>
        <li> Farah</li>
    </ul>
  </script>


<script type="text/javascript">

</script>


</head>
<body>
</body>
</html>

我认为问题出在 this.get('store') 中,当我尝试打印它的值时,它会打印 undefined。

【问题讨论】:

    标签: ember.js websocket store


    【解决方案1】:

    自 Ember Data 1.0 beta 1+ 起,您无需在 Ember Data 中定义存储。

    App.Store = DS.Store.extend({ 修订:13, 适配器:DS.SocketAdapter.create({}) });

    只需使用它就足够了:

    App.ApplicationAdapter = DS.SocketAdapter;
    

    存储被传递给find 函数,如果你愿意,你可以使用它。此外,您将超出onmessage 的范围,但这不是重点。

    推荐

    由于您的程序是双重的,我建议您使用依赖注入创建适配器/传输层。这是一个粗略的草稿

    交通

    DS.SocketTransport = Ember.Object.extend({
        uri: 'ws://localhost:8081/',
        type: 'post',
        ws: null,
        store: null,
        init: function(){
            var uri = this.get('uri'),
                type = this.get('type'),
                store = this.get('store'),
                ws = new WebSocket(uri);
    
            // callbacks
            ws.onopen = function() {
              console.log('Connection established /all');
            };
            ws.onclone = function() {
              console.log('Connection closed /' + 'all');
            };
            ws.onmessage = function(data) {
              // if this is random post data, side load
              store.load('post', data)
              console.log(data);
            };
    
            this._super();
        }
    });
    

    Web 套接字适配器

    App.MyWsAdapter = DS.RESTAdapter.extend({
      transport: null,
      find: function(store, type, id) {
        var transport = this.get('transport');
        // Do your thing here
        return new Ember.RSVP.Promise(function(resolve, reject){
          // use the transport here to send a message/get a message, containing
          // the json for the type and id mentioned above then use
          //resolve(json);
        });
    
      },
    
    });
    

    依赖注入

    App.initializer({
        name: "transport",
        after:['store'],
    
        initialize: function (container, application) {
          var store = container.lookup('store:main'),
              postTransport = application.PostTransport.create({store:store, type:'post'});
    
            register("my:postTranspot", postTransport);
            application.PostAdapter = App.MyWsAdapter.create({
              transport: postTransport
            });
        }
    });
    

    【讨论】:

    • 你有例子吗?我不清楚
    • 我举了一些一般想法的例子,未经测试,但应该给你一个想法。