簡體   English   中英

調用方法時流星進入路徑

[英]Meteor entering route when calling a method

有人可以向我解釋為什么當我在路由器中有集合代碼時會導致在調用方法時調用路由?

請考慮以下代碼

home.html的

<template name="home">
    {{ duplicate }}
    <form>
        <input type="text" name="test" value="somevalue">
        <input type="submit" value="Submit">
    </form>
</template>

的script.js

Template.home.events({
    'submit form': function (e) {
        e.preventDefault();
        console.log('Enter Meteor call');
        Meteor.call('createDoc', { 'test': e.target.test.value });
    }
});

route.js

Router.onBeforeAction(function () {
    console.log('Enter onBeforeAction');
    $('#loading').show();
    this.next();
});

Router.route('/', function () {
    console.log('Enter action');
    var foo = collection.findOne({ test: 'somevalue' }) ? 'true' : 'false';
    this.render('home', {
        data: {
            'duplicate' : foo
        }
    });

    Template.home.rendered = function () {
        console.log('Enter rendered');
        $('#loading').hide();
    };
});

methods.js

collection = new Mongo.Collection('collection');

Meteor.methods({
    createDoc: function (data) {
        console.log('Enter createDoc');
        collection.insert(data);
    }
});

問題是,如果我按下表單上的提交,在調用該方法之后,即使e.preventDefault()出現,路由器也會激活。 控制台日志清楚地顯示了此行為:

"Enter Meteor call" script.js:4:3
"Enter createDoc" methods.js:5:3
"Enter onBeforeAction" routes.js:2:2
"Enter action" routes.js:8:2
"Enter onBeforeAction" routes.js:2:2
"Enter action" routes.js:8:2

此外,您可以看到路由器被調用兩次,並且它永遠不會進入Template.home.rendered 這會導致加載div出現並且永不離開。 我可以確認正確插入數據。

但是,如果我刪除routes.js中的collection.findOne() ,則此行為將消失,一切都按預期工作。

問題

  • 為什么只有在路由中有collection.findOne()時才調用路由?

  • 為什么collection.findOne({ test: 'somevalue' })永遠不會返回路由中的任何內容? (我知道如何通過在script.js中使用Session變量和幫助器來解決這個問題,但我想確切地知道原因)

這在我的應用程序中導致了許多意外行為。 非常感謝你提前。

正如其他人所回答的那樣,問題來自Meteor將反應性地重新運行在被動上下文中運行的代碼,當且僅當該代碼發出對被動數據源的調用時。

在您的情況下,對findOne的調用是對響應數據源的調用以及Router.route('/', function () { // context });的上下文Router.route('/', function () { // context }); 是一個反應性的背景。

有兩個重要的工具可以讓你控制這種行為:一個是好的設計。 注意反應性並嘗試圍繞它設計代碼。 另一個是檢查Tracker.active並使用Tracker.nonreactive來避免反應數據上下文中的反應。

這應該回答你的第一個問題。 至於為什么你的findOne查詢永遠找不到任何東西:你是否已將數據從服務器發布到客戶端? 請查看Publish-Subscribe 你基本上需要:

// on the server
Meteor.publish('myPublication', function(author) {
     return collection.find();
});
// on the client
Meteor.subscribe('myPublication');

路徑中對collection.findOne()的調用正在偵聽數據庫上的任何新更改,每次在運行查詢的數據庫上保存文本。

一種可能的解決方案:Router.js

Router.onBeforeAction(function () {
  console.log('Enter onBeforeAction');
  $('#loading').show();
  this.next();
});



Router.route('/', {
  template: 'home',
  waitOn: function() {
    return Meteor.subscribe('collection');
  },
  data: function() {
    var foo = collection.findOne({ test: 'somevalue' }) ? 'true' : 'false';
    return {
        'duplicate': foo
    };
  },
  action: function() {
    this.render();
  }
});

以及server / publish.js上的發布文件

Meteor.publish('collection', function () {
  return collection.find();
});

我希望這可以幫助您解決問題。 最好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM