簡體   English   中英

當meteor方法拋出錯誤時如何刷新客戶端值?

[英]How to refresh client side value when meteor method throws an error?

我寫了一個改變對象的Meteor方法。 只有對象的所有者才能編輯屬性。

該方法因此檢查當前用戶和對象所有者的匹配。 如果它不匹配,則該方法拋出原因的異常。

此方法有效,因為更改未觸及集合,並且錯誤對象將返回給客戶端。

然而,編輯后的財產未更新以反映其實際價值。 如何觸發刷新值?

附加信息:我在前端使用React; 該對象未在前端代碼中明確更新(因此該方法似乎也在客戶端運行)。

一些代碼(簡化,命名改變,明顯的錯誤可能不在原文中;)

客戶端:

  saveCommentChanges(updatedComment) {
    Meteor.call('comment.updateComment', updatedComment, function (error, result) {
      if (error && error.error === "not-authorized") {
            Session.set("errorMessage", "You are only allowed to change own comments.");
      }
    });
  }

服務器端:

if (Meteor.isServer) {  
  Meteor.methods({
    'comment.updateComment'(comment) {
    check(comment, Object);

    origComment = Comments.findOne(comment._id);

    if (origComment.user != this.userId) {
      console.log('user does not match');
      throw new Meteor.Error('not-authorized');
    }

    let res = Comments.update(
      {'_id': comment._id},
      {$set: {date: comment.date,
          comment: comment.comment}
      }, {removeEmptyStrings: false});
    }
  }

更新后在客戶端刷新:

  1. 確保在服務器上發布數據,然后添加到控制器中的構造函數 - this.subscribe('Comments'); 請參閱AngularJS中的以下示例
  2. 服務器更新后,評論應該更新。 您可能還需要運行meteor remove autopublish以使前端正確更新。 流星服務器促使我這樣做

在您的情況下,不會過濾注釋,您可以根據注釋ID和用戶過濾更新。 如果沒有找到已存在的注釋,則更新將不起作用,您可以捕獲拋出錯誤。

  if (Meteor.isServer) { 
// This code only runs on the server
      Meteor.publish('comments', function publishComments() {
        return Comments.find({});
      });
  }

  Meteor.methods({
    'comment.updateComment'(comment) {
    check(comment, Object);

    origComment = Comments.findOne(comment._id);

// option 1
    if (origComment.user != this.userId) {
      console.log('user does not match');
      throw new Meteor.Error('not-authorized');
    }

// keep the same update here

// option 2
    let res = Comments.update(
       { '_id': comment._id,'user': origComment.user},
      {$set: {date: comment.date,
          comment: comment.comment}
      }, {removeEmptyStrings: false});
      return res;
    }
);

進口/組件/股/ stocks.html

<button type="submit" class="btn btn-success btn-sm m-2" 
ng-hide="{{$ctrl.currentUser === null}}"
ng-click="$ctrl.buyStock(stock.name, 1)">
   Buy 1 Share
</button>

進口/組件/股/ stocks.js

import angular from 'angular';
import angularMeteor from 'angular-meteor';
import template from './stocks.html';

import { Meteor } from 'meteor/meteor';
import { Stocks } from '../../api/Stocks.js';
import { UserStocks } from '../../api/UserStocks.js';

class StocksCtrl {

  constructor($scope) {
    $scope.viewModel(this);

    this.subscribe('stocks');
    this.subscribe('userStocks');

    // Return the data mostly right now
    this.helpers({
      currentUser() {
        return Meteor.user();
      },
      stocks() {
        const selector = {};
        // Show newest tasks at the top
        return Stocks.find(selector, {
          sort: {
            name: 1
          }
        });
      },
      userStocks() {
        return UserStocks.find({});
      }
    })
  }

  buyStock(stock, amt) {
    console.log("Buying stock processing...");

    // ADD TO UserStock
    Meteor.call('userStocks.buy', stock, amt, function(error, result) {
      if(error){
        console.log(error.reason);
        return;
      } 
      // log to console
      console.log("UserID: " + Meteor.userId() + "\n Username: " + Meteor.user().username 
        + "\n Message: Purchase of " + amt + " shares of " + stock + " was successful.");

      // alert the user
      alert("Purchase of " + amt + " shares of " + stock + " was successful.");
    });
    console.log("Buying stock complete.");
  }

}

export default angular.module('StocksApp', [
  angularMeteor
])
.component('stocksApp', {
  templateUrl: 'imports/components/stocks/stocks.html',
  controller: ['$scope', StocksCtrl]
});

進口/ API / UserStocks.js

import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';

export const UserStocks = new Mongo.Collection('userStocks');


if (Meteor.isServer) {
  // This code only runs on the server
  // Only publish tasks that are public or belong to the current user
  Meteor.publish('userStocks', function getUserStocks() {
    return UserStocks.find({
        ownerID: { $eq: this.userId }
      });
  });
}

Meteor.methods({
  'userStocks.buy' (stock, amount) {
    // Make sure the user is logged in before inserting a task
    if (!Meteor.userId()) {
      throw new Meteor.Error('not-authorized');
    }

    // if currently exists, increase the amount by the amount purchased
    // if it does not exit, the upsert true will create/insert
    const newID = UserStocks.update(
      { ownerID: { $eq: this.userId }, stock: { $eq: stock } },
      { $setOnInsert: { ownerID: this.userId, stock: stock}, $inc: {amt: amount} },
      { upsert: true, returnNewDocument: true}
    );

    return newID;
  }
});

服務器/ main.js

import '../imports/api/Stocks.js';
import '../imports/api/UserStocks.js';

暫無
暫無

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

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