Javascript 创建动态路由时出现余烬错误

Javascript 创建动态路由时出现余烬错误,javascript,ember.js,Javascript,Ember.js,如果已经有人问过我,我无法理解,我会道歉 我正在尝试将余烬动态路线与模板链接。它不起作用了。处理路由时,以下代码的错误为错误:favorite undefined不是函数 其思想是主页面应该显示通过Ajax返回的收藏夹列表。每个收藏夹都应该有一个链接。用户单击一个链接,收藏夹将被注入到同一页面上的相关模板中 主页正常工作。使用下面的代码,链接当前显示的是index.html/#/12345ab,其中12345ab是产品id HTML模板: <script type="text/x-hand

如果已经有人问过我,我无法理解,我会道歉

我正在尝试将余烬动态路线与模板链接。它不起作用了。处理路由时,以下代码的错误为
错误:favorite undefined不是函数

其思想是主页面应该显示通过Ajax返回的收藏夹列表。每个收藏夹都应该有一个链接。用户单击一个链接,收藏夹将被注入到同一页面上的相关模板中

主页正常工作。使用下面的代码,链接当前显示的是
index.html/#/12345ab
,其中12345ab是
产品id

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>
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);
    }
});
更新:

<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>
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);
    }
});
下面的答案给出了以下代码,但如果用户通过URL直接进入页面或直接刷新页面,则会失败,因为
收藏夹
模型尚未解析。确切的错误是:
无法读取未定义的属性“findBy”

App.FavoriteRoute = Ember.Route.extend({
    model: function(params) {
        return this.modelFor('favorites').findBy('product_id', params.product_id);
    }
});
更新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);
    }
});

从外观上看,您希望从父管线查找模型。你可以这样做:

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

<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>
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);
    }
});
问题是,您从父路由得到的承诺没有得到正确的解决。您正在返回承诺,但该承诺的结果未得到解决,即(return data.favorites)未解决承诺

更新至:

App.FavoritesRoute = Ember.Route.extend({
    model: function() {
      return new Promise(function(resolve, reject) {
        Ember.$.ajax('yourURL').then(
          function(data){
            resolve(data.favorites); 
        });
    });    
  }
});
还应包含此答案的初始反馈。我有一个与实际端点相对应的工作JSBin,以表明它是有效的:

另外,请注意作为字符串输入的params.product_id。您需要将其强制转换为所需的类型,以便findBy正常工作

另外,我还应该补充一点,Ember.$。ajax返回一个承诺,但您希望模型是data.favorites,这是外部承诺的需要。如果您刚刚返回了Ember.$.ajax并通过model.favorites访问了所有内容,您就不需要它了。

您的路由需要是子资源通过
#modelFor
访问父资源。但是,如果您的UI没有嵌套,则您的路由可能不应该嵌套,因为嵌套路由还连接了相应的视图层次结构

您始终可以根据ajax调用返回的数据子集来定义
收藏夹
路由的模型:

//routes/favorite.js
model: function() {
    return Ember.$.getJSON('/favorites').then(function(favorites) {
      return favorites.findBy('id', params.product_id');
    });
}
但是,每次用户输入/favorites
,以及每次输入
/favorites/:id`,都会多次调用顶级的
.getJSON('/favorites

相反,您可以让应用程序在输入时设置一次
FavoritesController
。这样,您可以共享数据,但
收藏夹
不必是
收藏夹
的子路径。它可能看起来像这样:

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

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


这样,JSON只加载一次,
ApplicationRouter
为您连接您的
FavoritesController
,数据与
favorite
资源共享。

在Ember IRC频道的帮助下,这就是工作代码。本质上,它为要渲染到的
收藏夹
收藏夹
模板创建索引模板。然后,
收藏夹
路由可以访问它的父路由
收藏夹
,但仍然渲染到相同的模板区域

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>

那(即
modelFor
)是我一直在寻找的。工作代码最后是
返回this.modelFor('favorites').findBy('product_id',params.product_id)
出于某种原因,它不喜欢
arrangedContent
部分,我需要返回整个内容。谢谢,还有一个问题。当通过URL(而不是链接到
)到达页面时,模型会出错。错误是
无法通过未定义的
读取findBy,这意味着当它不是来自收藏夹页面的链接时,找不到
收藏夹
模型。有什么建议吗?我想这是因为你把它们指定为资源vs路线。尝试将它们切换到嵌套路由。我更新了更新以包括
App.Router.map
。它仍然给出相同的错误,
无法读取未定义的
的findBy。我还尝试用
资源
替换
路线
部分。好的,我知道问题出在哪里了……我的问题解决了,因为父路线的模型立即得到了解决。这一切都归结为承诺…承诺,哈哈。我会修改我的答案以正确反映问题。这一切都是有意义的。对于最后一部分的实现,请使用
FavoriteRoute
。它正在返回未定义的
this.controllerFor('favorites')
返回正确的对象(至少,它有一个名为
model
的方法,该方法具有正确的数据)。但是,Find和findBy不返回任何内容。它是数组吗?尝试
.get('model')
maybe?以便从控制器获取模型。如果遵循一个链接,效果会很好。但是,如果刷新页面,代码会很好地调出
收藏夹
控制器(它有包含所有数据的model子对象),但是
get('model')
返回空。我不明白。。。有关当前代码,请参见更新#2。因此,这里不适合进行此类讨论。试着跳到IRC上的#余烬频道。很公平。谢谢你的帮助。