简体   繁体   English

创建动态路线时出现灰烬错误

[英]Ember error while creating dynamic routes

Apologies if this has already been asked and I couldn't figure that out. 抱歉,如果已经有人问过这个问题,我无法解决。

I am attempting to link an Ember dynamic Route with a Template. 我正在尝试将Ember动态路线与模板链接。 It's not working. 没用 The error for the below code is Error while processing route: favorite undefined is not a function 以下代码的Error while processing route: favorite undefined is not a functionError while processing route: favorite undefined is not a function

The idea is that the main page should show a list of favorites that are returned via Ajax. 这个想法是,主页应该显示通过Ajax返回的收藏夹列表。 Each favorite should have a link. 每个收藏夹都应有一个链接。 The user clicks a link and the favorite is injected into the relevant template on the same page. 用户单击一个链接,并将收藏夹注入到同一页面上的相关模板中。

The main page is working correctly. 主页工作正常。 With the code below, the links are currently showing index.html/#/12345ab where 12345ab is the product_id . 使用下面的代码,这些链接当前显示为index.html/#/12345ab ,其中12345ab是product_id

HTML Template: HTML模板:

<script type="text/x-handlebars" id="favorites">
{{#each favorite in arrangedContent}}
    <div class="productBox">
        {{#link-to 'favorite' favorite.product_id}}
            <img {{bind-attr src=favorite.product_image}} />
        {{/link-to}}
    </div>
{{/each}}

{{outlet}}

</script>

<script type="text/x-handlebars" id="favorite">
    <h2>{{product_name}}</h2>
    <img {{bind-attr src=product_image}} />
</script>

Router code: 路由器代码:

App.Router.map(function() {
    this.resource('favorites', { path: '/'});
    this.resource('favorite', { path: ':product_id' });
});

App.FavoritesRoute = Ember.Route.extend({
    model: function() {
        return Ember.$.ajax({
            //this returns correctly
        }).then(function(data) {
            return data.favorites;
        });
    }
});

App.FavoriteRoute = Ember.Route.extend({
    model: function(params) {
        return App.Favorites.findBy('product_id', params.product_id);
    }
});

Update: 更新:

The answer below gives the following code, but if the user goes directly to the page via the URL or a straight refresh, it fails due to the fact that the favorites model is not resolved yet. 下面的答案给出了以下代码,但是如果用户通过URL或直接刷新直接进入页面,则由于favorites模型尚未解析而失败。 Exact error is: Cannot read property 'findBy' of undefined 确切的错误是: Cannot read property 'findBy' of undefined

App.FavoriteRoute = Ember.Route.extend({
    model: function(params) {
        return this.modelFor('favorites').findBy('product_id', params.product_id);
    }
});

Update 2: Entire Router code: 更新2:整个路由器代码:

App.Router.map(function() {
    this.resource('favorites', { path: '/'});
    this.resource('favorite', { path: ':product_id' });
});

App.ApplicationRoute = Ember.Route.extend({
    model: function() {
        return new Promise(function(resolve, reject) {
            Ember.$.ajax({
                url: 'MY_URL',
                dataType: 'jsonp',
                jsonp: 'callback'
            }).then(function(data) {
                resolve(data.favorites);
            });
        });
    },

    setupController: function(controller, model) {
        return this.controllerFor('favorites').set('model', model);
    }
});

App.FavoriteRoute = Ember.Route.extend({
    model: function(
        return this.controllerFor('favorites').get('model').findBy('product_id', params.product_id);
    }
});

By the looks of it, you want to find the model from the parent route. 从外观上看,您想从父路线中找到模型。 You can do it likes so: 您可以这样:

App.FavoriteRoute = Ember.Route.extend({
   model: function(params) {
   this.modelFor('favorites').arrangedContent.findBy('product_id', params.product_id);
 }
});

UPDATE: 更新:

The problem is that your promise from the parent route isn't getting resolved correctly. 问题是您从父级路线获得的诺言没有得到正确解决。 You're returning a promise but the result of that promise isn't getting resolved ie (return data.favorites) is not resolving the promise. 您正在返回承诺,但是该承诺的结果没有得到解决,即(返回data.favorites)没有解决承诺。

Update it to: 更新到:

App.FavoritesRoute = Ember.Route.extend({
    model: function() {
      return new Promise(function(resolve, reject) {
        Ember.$.ajax('yourURL').then(
          function(data){
            resolve(data.favorites); 
        });
    });    
  }
});

Also incorporate the initial feedback from this answer. 还应结合此答案的初始反馈。 I have a working JSBin going against an actual endpoint to show it works: http://jsbin.com/boloya/3/edit 我有一个工作的JSBin与实际的端点对接,以显示其有效: http : //jsbin.com/boloya/3/edit

PS Look out for params.product_id, that comes in as a string. PS请注意params.product_id,它以字符串形式出现。 You made need to cast it to the required type in order for the findBy to work correctly. 您需要将其强制转换为所需的类型,以使findBy正常工作。

PSS I should also add, Ember.$.ajax returns a promise, but you want the model to be data.favorites which is the need for the outer promise. PSS我还应该添加Ember。$。ajax返回一个promise,但是您希望模型成为data.favorites,这是对外部诺言的需求。 If you just returned Ember.$.ajax and accessed everything via model.favorites you wouldn't need it. 如果您只是返回Ember。$。ajax并通过model.favorites访问了所有内容,则不需要它。

Your routes need to be nested for a child resource to have access to a parent via #modelFor . 您的路由需要嵌套 ,以使子资源可以通过#modelFor访问父#modelFor However, if your UI isn't nested, your routes probably shouldn't be, since nesting routes also wires up a corresponding view hierarchy. 但是,如果您的UI没有嵌套,那么路由就不应该嵌套,因为嵌套路由还会连接相应的视图层次结构。

You could always define the model for the favorite route in terms of a subset of the data returned by your ajax call: 您始终可以根据ajax调用返回的数据的子集来定义favorite路线的模型:

//routes/favorite.js
model: function() {
    return Ember.$.getJSON('/favorites').then(function(favorites) {
      return favorites.findBy('id', params.product_id');
    });
}

but then, the top-level .getJSON('/favorites ) call would be made multiple times, every time the user enters /favorites , and every time he enters /favorites/:id`. 但随后, call would be made multiple times, every time the user enters / favorites , and every time he enters call would be made multiple times, every time the user enters , and every time he enters / favorites /:id` , and every time he enters call would be made multiple times, every time the user enters顶级.getJSON('/favorites )。

Instead, you can have the application set up the FavoritesController once upon entry. 相反,您可以让应用程序在输入后立即设置“ FavoritesController控制器”。 That way you can share data, but favorite doesn't have to be a child route of favorites . 这样,您可以共享数据,但“ favorite不必是“ favorites的子路径。 It might look something this: 它可能看起来像这样:

//routes/application.js
model: function() {
    return Ember.$.getJSON('/favorites');
},

setupController: function(controller, model) {
  this.controllerFor('favorites').set('model', model);
}

and

//routes/favorite.js
model: function(params) {
  return this.controllerFor('favorites').find('id', params.id);
}

That way, the JSON is only loaded once, ApplicationRouter is wiring up your FavoritesController for you, and the data is shared with the favorite resource. 这样,JSON仅加载一次, ApplicationRouter为您连接FavoritesController ,并且数据与favorite资源共享。

With some help from the Ember IRC channel, this is the working code. 在Ember IRC频道的一些帮助下,这是工作代码。 In essence, it creates an Index template for both the favorites and the favorite template to render into. 本质上,它为favorites和要呈现到的favorite模板都创建了一个索引模板。 Then the favorite route can access it's parent route favorites and yet still render into the same template area. 然后, favorite路线可以访问其父路线favorites ,但仍渲染到同一模板区域中。

HTML HTML

<script type="text/x-handlebars">
    <h2>Welcome to Ember.js</h2>

    {{outlet}}
  </script>

  <script type="text/x-handlebars" id="favorites">
    {{outlet}}
  </script>

  <script type="text/x-handlebars" id="favorites/index">
{{#each favorite in arrangedContent}}
    <div class="productBox">
        {{#link-to 'favorite' favorite.product_id}}
            <img {{bind-attr src=favorite.product_image}} />
        {{/link-to}}
    </div>
{{/each}}

{{outlet}}

</script>

<script type="text/x-handlebars" id="favorite">
    <h2>{{product_name}}</h2>
    <img {{bind-attr src=product_image}} />
</script>

Router.js Router.js

App.Router.map(function() {
    this.resource('favorites', { path: '/'}, function () {
      this.resource('favorite', { path: ':product_id' });
    });
});

App.IndexRoute = Ember.Route.extend({
  redirect: function () {
    this.replace('favorites');
  }
});

App.FavoritesRoute = Ember.Route.extend({
    model: function() {
        return new Promise(function(resolve) {
            Ember.$.ajax({
                url: 'MY_URL',
                dataType: 'jsonp',
                jsonp: 'callback'
            }).then(function(data) {
                resolve(data.favorites);
            });
        });
    }
});

App.FavoriteRoute = Ember.Route.extend({
  model: function (params) {
     return this.modelFor('favorites').findBy('product_id', params.product_id);
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM