2015-08-25 117 views
0

我花了好一个半小时试图弄清楚这里有什么问题,而且我没有任何运气。真的很感谢一些帮助,提前致谢!流星forEach()无法解释的改变传递的变量

我的问题似乎是在下面的sendMailing()meteor方法的“Roles.getUsersInRole(mailingAttributes.role).forEach”循环中,由客户端调用传递的变量“mailingAttributes”以某种方式被覆盖,等通过foreach()循环第二轮,没有什么的.replace()的替换

1 -这里是一个被发送到sendMailing对象的实例()流星法,以及forEach()循环首次运行时如何出现

{ 
    role:  "admin", //Which user group to send the email to 
    subject:  "Hello [[firstName]]!", //Email subject 
    html:  "<h1>Hello [[firstName]] [[lastName]], how do you do?</h1>", //HTML Email 
    text:  "Hello [[firstName]] [[lastName]], how do you do?" //Plain Text Email 
} 

2 -现在在foreach()将用户对象和替换与用户属性的占位符(第一&姓)

3 -鉴于用户鲍勃·琼斯,这里是如何同一个对象的示例出现第二次foreach()循环中运行,其中该物体应该是储存

{ 
    role:  "admin", //Which user group to send the email to 
    subject:  "Hello Bob!", //Email subject 
    html:  "<h1>Hello Bob Jones, how do you do?</h1>", //HTML Email 
    text:  "Hello Bob Jones, how do you do?" //Plain Text Email 
} 

所以没有什么的.replaces()来改变......但我永远不会改变的变量(mailingAttributes)...所以例1和2之间应该没有区别

这里是我的实际代码:

function sendMailingEmail(mailingAttributes) { 
    //Send email 
    Email.send({ 
     from: '[email protected]', 
     to: mailingAttributes.to, 
     subject: mailingAttributes.subject, 
     html: mailingAttributes.html, 
     text: mailingAttributes.text, 
    }); 
} 

//Set up rate limiting on the email send function 
var sendMail = rateLimit(sendMailingEmail, 75); // wait at least 75 milliseconds between calls (1 second/14 emails) 

Meteor.methods({ 
    sendMailing: function(mailingAttributes) { 

     //Check incoming attributes 
     check(mailingAttributes, { 
      role:  String, 
      subject:  String, 
      html:  String, 
      text:  String 
     }); 

     // Confirm the user is logged in 
     if (this.userId === null || !Roles.userIsInRole(this.userId, 'admin')) 
      throw new Meteor.Error(401, 'You must be logged in and authorized'); 

     Roles.getUsersInRole(mailingAttributes.role).forEach(function(userObject) { 
      //Create a temporary copy of the passed attributes 
      var userMailingAttributes = mailingAttributes; 

      //Make sure the user is subscribed to mailings 
      if (userObject.profile.subscribed === true) { 
       //Replace placeholders in text with user profile information 
       userMailingAttributes.subject = userMailingAttributes.subject.replace("[[firstName]]", userObject.profile.firstName).replace("[[lastName]]", userObject.profile.lastName); 
       userMailingAttributes.text = userMailingAttributes.text.replace("[[firstName]]", userObject.profile.firstName).replace("[[lastName]]", userObject.profile.lastName); 
       userMailingAttributes.html = userMailingAttributes.html.replace("[[firstName]]", userObject.profile.firstName).replace("[[lastName]]", userObject.profile.lastName); 
       userMailingAttributes.to = userObject.emails[0].address; 

       //Call the rate limited function, passing along the temporary copy of passed attributes (edited above) 
       sendMail(userMailingAttributes); 
      } 
     }); 
    } 
}); 

我使用的alanning:角色& dandv:限速包

回答

1

的问题是这样的:

//Create a temporary copy of the passed attributes 
var userMailingAttributes = mailingAttributes; 

不创建传递的属性的临时副本 - 它创建一个新的引用指向内存中的相同位置。如果你改变了那个,你正在改变另一个。

你想要做的是clone the object并使用克隆的对象而不是对同一对象的引用。

+0

使用了Underscore的_.clone(),它像一个魅力一样工作!非常感谢你指点我正确的方向! – DanielRHarris

+0

注意:使用下划线的_.clone保存对嵌套元素的引用。虽然你没有在这里做,如果你想在嵌套对象上使用它,你应该检查出lodash的cloneDeep https://lodash.com/docs#cloneDeep – challett