如何使用 Angular 制作电子邮件网页应用

分享于 

43分钟阅读

Web开发

  繁體

介绍

我们将使用 Angular JS创建一个电子邮件应用程序。 首先,我们将使用AngularJS和HTML构建前端,最后我们将在服务器部分中添加。

我们将学习 Angular,在我们进行的时候,正确地解释和解释概念。 因为我们没有在最终执行服务器部分,所以我们需要在代码中右键单击该数据。 我认为这不仅是一种好的学习方法,它是构建应用程序的一个好方法。

首先,我们需要样板 HTML。 这里HTML将包含所有必需的库。 我们将使用 Bootstrap 来进行外观和感觉,当然是 Angular。

下面是代码的外观:

<!DOCTYPEhtml><html><head><scriptsrc="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script><scriptsrc="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script><linkrel="stylesheet"type="text/css"href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css"/></head><body><divclass="container"></div></body></html>

首先,我们将重点关注与管理电子邮件相关的功能,这意味着我们不会用户登录。

我们要处理的第一件事是电子邮件 List。 从这个屏幕,我们应该能够看到电子邮件是谁,电子邮件的主题,以及当我们收到它。

首先,我们将为这个 table 编写 HTML,然后我们将使用 Angular 动态生成它。 以下是 static 版本的HTML:

<tableclass="table table-bordered table-condensed"><tbody><tr><td>Guinan</td><td>It's an Earth drink. Prune juice.</td><td>Dec 24</td></tr><tr><td>Beverly Crusher</td><td>Captain always push themselves too hard.</td><td>Dec 23</td></tr><tr><td>Mom</td><td>Don't forget to wear clean underwear today.</td><td>Nov 22</td></tr></tbody></table>

table 上的类是 Bootstrap 类,使 table 看起来不错。 这就是它的样子:

为了使用 Angular,我们将逐步逐步地逐步生成这个表,以详细介绍几个概念。 首先,我们将尝试使用 Angular 表达式来替换其中一个数据块。 将 Guinan 替换为 {{"Guinan Test" }} 这将导致 Guinan Test 显示而不是 Guinan

但这并不是。 发生以下情况:

这是因为AngularJS不会自动应用自身。 你必须告诉 Angular 页面的哪些部分在页面上应用。 通过添加,属性,可以在任何级别添加该属性,让我们将它添加到容器 <div> 标记中。

你的HTML标记应该如下所示:

<divclass="container"ng-app>

刷新时,你应该看到括号中的值 inside:

表达式允许将JavaScript直接嵌入到HTML中。 ( 技术上它不是 JavaScript,但这是另一个主题)。 在现实世界中,没有必要使用表达式来显示 string,我在这里进行引入概念。

基本上,Angular 运行代码 inside的双花括号并呈现结果。 例如你将该表达式替换为:

{{ "Guinan" + "" + "Smith" }}

如果用以下方法替换了表达式:

{{ 10 * 3 }}

你会得到:

这些不是真实的例子,在我们已经知道答案的情况下,使用乘法是没有意义的。 真正有趣的是,当我们开始使用数据表达式时。

所以我们继续做这个 table 数据驱动。 现在我们已经使用 ng-app 属性以便 Angular 知道要处理的HTML部分。 Angular 调用这些指令。现在我们将使用 ng-init 属性初始化一些数据,然后更新一个数据。

我们可以在任何地方使用这个属性。 我把它放在 <tbody> 标签里。 因此,我的<tbody> 标记如下所示:

<tbodyng-init="email={from: 'John', subject: 'I love angular', date: 'Jan 1'}">

现在,我将更新 table 中的第一行以使用该数据。 从这个角度:

<tr><td>{{ 10 * 3 }}</td><td>It's an Earth drink. Prune juice.</td><td>Dec 24</td></tr>

对此:

<tr><td>{{ email.from }}</td><td>{{ email.subject }}</td><td>{{ email.date }}</td></tr>

当我运行它的时候,我得到了这样的结果:

现在,让我们来做一个电子邮件,而不是一个电子邮件,然后为每个电子邮件显示一行。 为此,我们必须更改" ng-init",以便它创建一个 array,然后使用另一个 Angular 指令对每个电子邮件重复HTML行。 为此,我们使用另一个名为" ng-repeat"的指令。

因此,将 ng-init 更改为:

<tbodyng-init=" emails = [
 { from: 'John', subject: 'I love angular', date: 'Jan 1' },
 { from: 'Jack', subject: 'Angular and I are just friends', date: 'Feb 15' },
 { from: 'Ember', subject: 'I hate you Angular!', date: 'Dec 8' }
 ]
">

然后将以下 ng-repeat 属性和值添加到 <tr> 标记中:

ng-repeat="email in emails"

所以它看起来像这样:

<trng-repeat="email in emails">

运行它时,应该得到以下信息:

现在我们有一个动态生成的table。 问题是数据都在HTML中,好的是,让我们来修复这个问题。

让我们从HTML中将电子邮件 array 初始化为它属于JavaScript的位置。 为此,我们必须创建一个 Angular 调用控制器的特殊函数。 然后,使用 ng-controller 指令将控制器与一部分HTML关联起来- 与我们在 ng-app 中做的相似。

因此,将下面的代码添加到你的JavaScript:

function EmailController($scope) {
 $scope.emails = [
 { from: 'John', subject: 'I love angular', date: 'Jan 1' },
 { from: 'Jack', subject: 'Angular and I are just friends', date: 'Feb 15' },
 { from: 'Ember', subject: 'I hate you Angular!', date: 'Dec 8' }
 ];
}

然后在HTML中,添加 ng-controller 指令并将它的赋值为 EmailController。 对于任何元素,可以使用这个指令,但是只有该元素及其子元素可以访问控制器中创建的电子邮件变量,因此应该将它的分配给 <tr> 标签的父元素。 我将把它添加到 table 标签中,这样它看起来就像这样:

<tableng-controller="EmailController"class="table table-border table-condensed">

如果你运行它,一切都应该完全一样。 更改的唯一方法是,不要使用 inside 初始化的电子邮件,它现在初始化 inside 控制器函数。

你是否注意到控制器函数有一个名为 $scope的参数? 这就是在控制器和HTML之间共享数据的方式。 控制器在 $scope 中创建的任何变量都可以由HTML访问,反之亦然。

现在我们将添加点击电子邮件并查看它的内容的能力。 我们将使用 Bootstrap Modal 对话框HTML的标准来创建电子邮件弹出式菜单。 为这里,添加以下 HTML below 你的table:

<divclass="modal"><divclass="modal-header"><buttontype="button"class="close">×</button><h3>Subject</h3></div><divclass="modal-body"><strong>From:</strong> Steve <br/><strong>Date:</strong> Jan 2 <br/><br/><p> Hey You, <br/><br/> How you doing?<br/><br/> Sincerely<br/> Your Bro
 </p></div><divclass="modal-footer"><ahref="#"class="btn btn-primary">Close</a></div></div>

运行这里命令时,你应该看到一个与你的table 类似的弹出窗口,如下所示:

现在,当用户点击 List 上的电子邮件时,我们只希望弹出这个弹出窗口。 所以首先,我们需要一种控制它的可见性的方法。 我们将它绑定到一个变量,当变量是 true 时,当它是 false 时,它不是可以见的。

首先让我们在控制器中创建变量,让我们称它为 isPopupVisible,让我们将它设置为 false。 就像这样:

$scope.isPopupVisible = false;

你的控制器应该类似于下面这样:

function EmailController($scope) {
 $scope.isPopupVisible = false;
 $scope.emails = [
 { from: 'John', subject: 'I love angular', date: 'Jan 1' },
 { from: 'Jack', subject: 'Angular and I are just friends', date: 'Feb 15' },
 { from: 'Ember', subject: 'I hate you Angular!', date: 'Dec 8' }
 ];
}

现在我们将 ng-show 指令添加到弹出菜单中,以便将它绑定到该变量。 为此,请将以下指令添加到模式 div 中:

ng-show="isPopupVisible"

它应该是这样的:

<divclass="modal"ng-show="isPopupVisible">

现在我们已经将弹出窗口的可见性绑定到 isPopupVisible 变量,我们需要一种方法将该变量设置为 true。 那么让我们把 click 事件连接到电子邮件 List。 首先,创建一个将该变量设置为 true的函数,我们将它的命名为 showPopup(),如下所示:

$scope.showPopup = function () {
 $scope.isPopupVisible = true;
};

你的控制器现在应该如下所示:

function EmailController($scope) {
 $scope.isPopupVisible = false;
 $scope.showPopup = function () {
 $scope.isPopupVisible = true;
 };
 $scope.emails = [
 { from: 'John', subject: 'I love angular', date: 'Jan 1' },
 { from: 'Jack', subject: 'Angular and I are just friends', date: 'Feb 15' },
 { from: 'Ember', subject: 'I hate you Angular!', date: 'Dec 8' }
 ];
}

由于每个电子邮件都对应一行,所以我们将在行级别进行。 我们将使用 Angular 指令的ng-click 从每行调用这里函数,如下所示:

ng-click="showPopup()"

你的<tr> 标记如下所示:

<trng-repeat="email in emails"ng-click="showPopup()">

在这个工作开始之前我们还得再做一个。 在 上面 ng-controller 中,如果你记得将控制器应用到它的元素和子元素。 上次我们把它放到 <table> 上,但是由于模态HTML在 table 之外,我们需要将这个指令移动到容器的一级。 容器 <div> 应如下所示:

<divclass="container"ng-appng-controller="EmailController">

现在你有一个弹出窗口,当你点击电子邮件。 你可能会马上注意到,没有办法关闭它。 让我们创建另一个名为 closePopup()的函数,将 isPopupVisible 设置为 false。 然后让我们向关闭按钮。× 中添加一个 ng-click 指令,并拥有关闭按钮调用。

很好现在我们有一个打开和关闭的弹出窗口。 现在让我们来显示电子邮件的内容。 为这里,我们需要修改 showPopup() 以包括一个参数,以指定要显示的电子邮件。 然后,我们需要将该电子邮件存储在一个变量中并将它的绑定到弹出窗口。 finally,当用户点击列表时,我们需要将电子邮件传递给函数。

因此,修改函数以如下所示:

$scope.showPopup = function (email) {
 $scope.isPopupVisible = true;
 $scope.selectedEmail = email;
};

然后修改模式的标记以使用来自 selectedEmail的数据。 它应该从以下方面改变:

<divclass="modal"ng-show="isPopupVisible"><divclass="modal-header"><buttontype="button"class="close"ng-click="closePopup()">×</button><h3>Subject</h3></div><divclass="modal-body"><strong>From:</strong> Steve <br/><strong>Date:</strong> Jan 2 <br/><br/><p> Hey You, <br/><br/> How you doing?<br/><br/> Sincerely<br/> Your Bro
 </p></div><divclass="modal-footer"><ahref="#"class="btn btn-primary"ng-click="closePopup()">Close</a></div></div>

对此:

<divclass="modal"ng-show="isPopupVisible"><divclass="modal-header"><buttontype="button"class="close"ng-click="closePopup()">×</button><h3>{{selectedEmail.subject}}</h3></div><divclass="modal-body"><strong>From:</strong> {{selectedEmail.from}} <br/><strong>Date:</strong> {{selectedEmail.date}} <br/><br/><p> Hey You, <br/><br/> How you doing?<br/><br/> Sincerely<br/> Your Bro
 </p></div><divclass="modal-footer"><ahref="#"class="btn btn-primary"ng-click="closePopup()">Close</a></div></div>

最后,在 table 中更改对 showPopup()的调用以传递电子邮件。 就像这样:

ng-click="showPopup(email)"

你的<tr> 标记应如下所示:

<trng-repeat="email in emails"ng-click="showPopup(email)">

请注意,email 是我们在 ng-repeat 中分配的NAME。 当你单击它时,弹出窗口将显示你单击的电子邮件的内容。

我们唯一不显示的是电子邮件 body。 现在让我们来吧。让我们修改电子邮件的array 以包含电子邮件正文。

$scope.emails = [
 {
 from: 'John',
 subject: 'I love angular',
 date: 'Jan 1',
 body: 'hello world!'
 },
 {
 from: 'Jack',
 subject: 'Angular and I are just friends',
 date: 'Feb 15',
 body: 'just kidding'
 },
 {
 from: 'Ember',
 subject: 'I hate you Angular!',
 date: 'Dec 8',
 body: 'wassup dude'
 }
];

现在更新模式的标记,以便它在模式的body 中显示该副本。

现在我们要添加功能来撰写电子邮件。 对于compose电子邮件 popup,我们需要 3个字段和 2个按钮。 一个字段,用于地址,另一个用于主题,一个用于电子邮件的body。 一个按钮发送,另一个按钮取消。 我们的HTML如下所示:

<divclass="modal"><divclass="modal-header"><buttontype="button"class="close"">×</button><h3>Compose Email</h3></div><divclass="modal-body"><form><inputtype="text"placeholder="To"style="width:95%;"><br/><inputtype="text"placeholder="Subject"style="width:95%;"><br/><textareastyle="width:95%;"rows="10"></textarea></form></div><divclass="modal-footer"><ahref="#"class="btn">Close</a><ahref="#"class="btn btn-primary">Send</a></div></div>

输出如下所示:

就像前面所做的,我们希望添加一个变量和一些函数来控制可见性。 既然我们已经介绍了如何做到这一点,我将不会在这里深入讨论。 总之,我们需要执行以下操作:

  • 将变量 isComposePopupVisible 添加到控制器
  • 创建将它设置为 true的函数 showComposePopup()
  • 创建将它设置为 false的函数 closeComposePopup()
  • ng-show="isComposePopupVisible" 添加到模式
  • × 和"关闭"按钮中添加了 ng-click="closeComposePopup()"
  • 在电子邮件列表下添加了一个撰写按钮:
  • <button class="btn btn-primary">Compose</button>
  • ng-click="showComposePopup()" 添加到按钮

现在我们想捕获用户输入的信息,所以我们将把文本框绑定到对象的字段。 类似于我们使用 selectedEmail 变量使用电子邮件弹出菜单。

不同的是,我们使用的是电子邮件弹出式表达式,表达式用于呈现数据。 这种情况下,我们将使用 ng-model 指令,因为它是双向绑定。 我指的是,如果用户输入到输入字段中,我们希望变量自动更新。 同样,如果控制器改变了一个变量的值,那么我们希望输入能够自动更新以反映。

要开始,请将 composeEmail 变量作为空对象添加到控制器,如下所示:

$scope.composeEmail = {};

然后通过分别向 <input><textarea> 添加 ng-model="composeEmail.to"ng-model="composeEmail.body",更新HTML以绑定到该对象中的字段。 所以它看起来像这样:

<inputtype="text"placeholder="To"ng-model="composeEmail.to"><inputtype="text"placeholder="To"ng-model="composeEmail.subject"><textarearows="10"ng-model="composeEmail.body"></textarea>

现在让我们确认这实际上是绑定,当用户单击"发送"按钮时显示带有这里信息的警告框。 让我们在控制器中创建一个函数,绑定到"发送"按钮,并让它显示 composeEmail 变量中的值。 你的函数应该如下所示:

$scope.sendEmail = function() {
 alert($scope.composeEmail.to
 + "" + $scope.composeEmail.subject
 + "" + $scope.composeEmail.body);
};

现在,让我们像这样将" Send"按钮绑定到它:

<br/><ahref="#"class="btn btn-primary"ng-click="sendEmail()">Send</a>

现在通过单击"撰写"按钮。向"到"中的和"正文"字段输入一些信息并单击"发送"来测试它。 你应该看到你在弹出式菜单中输入的内容。

现在让我们再加一些东西。 我们要做的第一件事是让弹出窗口消失。 要做到这一点,我们将添加 $scope.isComposePopupVisible = false; 如果你再次点击按钮而不是空的,你会看到上次输入的信息。 让我们通过将一个空对象分配给 showComposePopup() 函数中的composeEmail 来纠正这个问题。 完成后,你的函数应该如下所示:

$scope.sendEmail = function() {
 $scope.isComposePopupVisible = false;
 alert($scope.composeEmail.to
 + "" + $scope.composeEmail.subject
 + "" + $scope.composeEmail.body);
};
$scope.showComposePopup = function() {
 $scope.composeEmail = {};
 $scope.isComposePopupVisible = true;
};

现在让我们做一些比显示警告框更有趣的事情。 通常你发送的邮件会进入你的"已经发送"文件夹。 现在,我们只有一个收件箱。 首先让我们添加一个"已经发送"文件夹,并使用标签在它和"收件箱"之间切换。

让我们从HTML开始。 将下面的HTML添加到容器的顶部:

<ulclass="nav nav-tabs"><li><a>Inbox</a></li><li><a>Sent</a></li></ul>

它应该是这样的:

和其他的"angularized"一样,我们需要一个变量来跟踪我们在哪个标签中。 我们把它称为 activeTab,默认情况下,我们将它设置为" inbox"。

$scope.activeTab = "inbox";

现在,当用户单击"收件箱"或者"已经发送"时,让我们更改这个变量。 我们可以做正确的inside ng-click 就像这个 ng-click="activeTab='inbox'"。 因此,你的HTML看起来如下所示:

<ulclass="nav nav-tabs"><li><ang-click="activeTab='inbox'">Inbox</a></li><li><ang-click="activeTab='sent'">Sent</a></li></ul>

现在,让我们只显示当前的电子邮件 List,当activeTab为" inbox"时,使用如下的ng-show 指令:

ng-show="activeTab=='inbox'"

现在很好了。现在点击"已经发送"标签,邮件列表消失了,当你点击" inbox",它会再次出现。

问题是你无法确定选中哪个选项卡。 Bootstrap 有一种选择选项卡的方法,它需要将活动的CSS类添加到选项卡元素的选定 <li> 中。 请参见 http://getbootstrap.com/2.3.2/javascript.html#tabs

因此我们需要一种方法来添加这个类,但是只有当 activeTab 变量被设置为相应值时。 因此" inbox"的<li> 只有在 activeTab 设置为" inbox"时才应该有一个活动类。 为此,我们使用 ng-class 指令。 如果值为 true,则这里指令将获取一个对象,如果该值是,则该对象将按该名称添加一个类。

例如在下面的代码中,Angular 将活动的CSS类添加到 <li> 元素中:

<ling-class="{active: true}">Inbox</li>

结果是:

<liclass="active">Inbox</li>

如果值是 false,则本例中的类将为空。 我们希望用适当的条件替换 true,如下所示:

<ling-class="{active: activeTab == 'inbox'}">Inbox</li>

你的final 代码应该类似于下面这样:

<ulclass="nav nav-tabs"><ling-class="{active: activeTab == 'inbox'}"><ang-click="activeTab='inbox'">Inbox</a></li><ling-class="{active: activeTab == 'sent'}"><ang-click="activeTab='sent'">Sent</a></li></ul>

应该是这样的:

现在唯一剩下的就是在"已经发送"标签中显示发送的邮件。 为此,我们基本上需要复制我们为收件箱所做的事情:

  • 在控制器中创建一个变量 sentEmails 分配一个空的array
  • 复制电子邮件列表的HTML table
  • ng-repeat 更改为 ng-repeat="email in sentEmails"
  • ng-show 条件更改为 ng-show="activeTab=='sent'"
  • {{ email.from }} 更改为 {{ email.to }}

你可以通过向 sentEmails array 中添加对象并确认它们显示出来来进行快速测试。

现在我们要做的是将发送的电子邮件添加到这个 array。 这部分纯粹是 JavaScript,我们只使用JavaScript函数 Array.push()composeEmail 添加到 sentEmails array。 就像这样:

$scope.sentEmails.push($scope.composeEmail);

另外,我们可以利用这个机会来删除警报,因为现在我们可以在"已经发送"标签中看到发送的电子邮件。 YoursendEmail() 函数应如下所示:

$scope.sendEmail = function() {
 $scope.isComposePopupVisible = false;
 $scope.sentEmails.push($scope.composeEmail);
};

到目前为止,我们只能触摸到一些东西。 例如发送电子邮件并转到"已经发送"选项卡后,你将看到日期列是空白的。 因为日期字段没有绑定到表单上的任何内容,所以它不会被填充。 这是因为日期应该是你发送电子邮件的日期,而不是用户指定的日期。 通常,这将在服务器上完成,因为我们没有服务器部分,但是我们将在 sendEmail() 函数中执行这里操作。 你可以直接指定 date 属性,如下所示:

$scope.composeEmail.date = new Date();

如果你通过发送邮件来测试这个问题,你会发现另一个问题。 日期看起来像这个" 2013-12-27T21:47:01.678Z"。 我不喜欢,我希望它看起来像收件箱中的日期,但那些日期是 string s,不是实际的JavaScript date 对象。

幸好 Angular 为我们提供了一种使用"筛选器"格式设置表达式格式的方法。 在我们的例子中,我们可以通过更改这个 {{ email.date }} 来修改日期的显示方式 {{ email.date | date:'MMM d' }} 注意:如果你注意到,我们做的是添加| 日期:'嗯'到现有表达式末尾。

竖线,称为管道( | ),是告诉 Angular 通过过滤器运行数据的方式。 本例中的过滤器是日期,冒号将过滤器与参数分离,后面的字符串告诉日期过滤器如何格式化数据。 有关设置日期格式的不同方法,请参阅 Angular 文档: http://docs.angularjs.org/api/ng.filter:date http://jsfiddle.net/luisperezphd/UKYnz/

好的,再清理几件东西。 例如,如果你发送电子邮件,然后点击它看它的内容,弹出的日期仍然很丑。 因为"来自"字段是空的,所以在发送日期时,它是我们必须指定的。 finally,没有"到"字段。 这些解决方案与我们之前处理的问题相同,因此我们知道解决方案:

  • 在表达式末尾追加| 日期以使用过滤器格式设置日期格式
  • 指定 $scope.composeEmail.fromsendEmail() 函数中的值" me"
  • 将" To"字段和表达式添加到 HTML
  • 将" To"值分配给控制器中的示例电子邮件

现在我们将对它的余的功能进行一些工作,以便精确地发布应用程序,如转发和回复电子邮件。 我们将通过重用compose电子邮件功能implement来实现它。 我会快速的进行,因为它是直接的,我们没有引入任何新的概念。

首先,我们需要将" Reply"和" Forward"按钮添加到电子邮件细节弹出式菜单中。

<ahref="#"class="btn">Forward</a><ahref="#"class="btn">Reply</a>

应该是这样的:

然后,在控制器上创建 ReplyForward 函数:

$scope.forward = function() {
};
$scope.reply = function() {
};

然后,我们将这些函数绑定到按钮。

<ahref="#"class="btn"ng-click="forward()">Forward</a><ahref="#"class="btn"ng-click="reply()">Reply</a>

现在,我们需要执行以下操作:

  • 隐藏视图详细信息弹出式菜单
  • 填充 composeEmail 对象
  • 它是如何填充的取决于它是答复还是转发
  • 显示撰写电子邮件弹出式菜单

就是这样,下面是注释的reply() 函数:

$scope.reply = function() {
 // hide the view details popup $scope.isPopupVisible = false;
 // create an empty composeEmail object the compose email popup is bound to $scope.composeEmail = {};
 // copy the data from selectedEmail into composeEmail angular.copy($scope.selectedEmail, $scope.composeEmail);
 // edit the body to prefix it with a line and the original email information $scope.composeEmail.body =
 "n-------------------------------n" + "from:" + $scope.composeEmail.from + "n" + "sent:" + $scope.composeEmail.date + "n" + "to:" + $scope.composeEmail.to + "n" + "subject:" + $scope.composeEmail.subject + "n" + $scope.composeEmail.body;
 // prefix the subject with"RE:" $scope.composeEmail.subject = "RE:" + $scope.composeEmail.subject;
 // the email is going to the person who sent it to us// so populate the to with from $scope.composeEmail.to = $scope.composeEmail.from;
 // it's coming from us $scope.composeEmail.from = "me";
 // show the compose email popup $scope.isComposePopupVisible = true;
};

单击"答复"时,撰写窗口应如下所示:

forward() 实际上与这里相同,惟一的区别是主题以"fw:"为前缀,而不是"vt:",而不是发送方,而是空白。

如果你现在运行这个,你会发现 2个。 第一,在"已经发送"标签中,邮件按发送顺序从上面列表中列出。 我们希望以相反的顺序显示,所以你发送的最后一个邮件显示在顶部。 为此,我们可以更改将 composeEmail 添加到 sentEmails array的代码行。 我们将使用 splice()push() 添加到 array的末尾,而不是使用添加电子邮件。 就像这样:

//$scope.sentEmails.push($scope.composeEmail);//OLD$scope.sentEmails.splice(0,0,$scope.composeEmail); // NEW

这里外,如果你打开一个发送的电子邮件,所有新添加的文本,你会看到所有的文本互相运行。 我们可以用一个小的CSS来解决这个问题。 我们将使用 inline CSS一次。 我们将把电子邮件的body 包装在 <span> 标签周围,并将 CSS white-space 属性设置为 pre。 这将告诉浏览器honor分行符。 就像这样:

<spanstyle="white-space:pre">{{selectedEmail.body}}</span>

在用户界面方面,我们的应用现在相当完整。 但是在它可以是真正的应用之前,它必须能够与服务器交谈,以实现发送和存储电子邮件。 这就是我们在这篇文章中要做的。

现在我要做的第一件事是设置服务器部分。 我有意留下这篇文章,因为我希望你能够尝试 Angular 代码,而不必强制你设置本地开发环境。 而且,无论他们使用的服务器技术- PHP。.NET。node.js 等等,我都希望它对所有人都有用。

显然,我将无法越过这一点。 毕竟,如果没有服务器,我无法向你展示如何与服务器通信,这意味着我必须选择一种技术。 我将使用 ASP.NET MVC。 我还将尽量详细描述服务器部分,以便它对你来说也有用,无论你使用什么服务器技术。

ASP.NET MVC入门

对于那些不熟悉 ASP.NET MVC的人来说,一。 在这种类型的web应用程序中,url映射到类和。 例如如果用户在他们的网页浏览器中输入了 URL http://localhost/Home/Index,它会触发类 HomeController 中的方法 Index() 以运行。

方法可以选择是否返回数据或者 HTML。 HTML存储在一个单独的文件中,称为视图。 这些视图的扩展名为 。 类似于控制器,根据URL选择正确的视图,再次为 URL http://localhost/Home/View, 使用存储在 folderViewsHomeIndex.cshtml 中的视图。

我当然简化了,但这个解释应该符合我们的目的。

回到应用程序

首先,我们需要在 Visual Studio 中创建一个 ASP.NET MVC项目。 我选择从一个空项目开始,添加一个名为 HomeController的控制器类。 一个叫做 Index的动作方法。 在我看来,我包括了在开始时提到的CSS。JavaScript和 HTML。

现在让我们更新应用程序,从服务器获取电子邮件 List,而不是在JavaScript中硬编码它。 首先,我们将在 ASP.NET 控制器上创建该方法:

public ActionResult GetEmails()
{
 return Json(new[] {
 new {
 from = "Riker",
 to = "me",
 subject = "Nice to meet you, Pinocchio",
 date = "Jan 8",
 body = "That and helping Data finish 'Pop Goes the Weasel'. Also counts as a CMOH." },
 new {
 from = "Picard",
 to = "me",
 subject = "I'm sorry, this is becoming a speech",
 date = "Jan 7",
 body = "But then I'm entitled, I'm the captain." },
 new {
 from = "Data",
 to = "me",
 subject = "Could you please continue...",
 date = "Jan 6",
 body = "...the petty bickering? I find it most intriguing." },
 new {
 from = "Troi",
 to = "me",
 subject = "But you spell knife with a 'k'",
 date = "Jan 5",
 body = "I spell 'knife' with an 'n', but then I never could spell." },
 });
}

在本例中,我们将返回一个 static List。 我们使用 Json() 方法告诉 ASP.NET 将这些数据返回给浏览器作为 JSON。

现在,我们将用一个调用来替换JavaScript中的硬编码 List。 JavaScript在视图中与我们的HTML ( /Views/Home/Index.cshtml ) 一起。 因此,替换:

$scope.emails = [
 {
 from: 'John',
 to: 'me',
 subject: 'I love angular',
 date: 'Jan 1',
 body: 'hello world!' },
 {
 from: 'Jack',
 to: 'me',
 subject: 'Angular and I are just friends',
 date: 'Feb 15',
 body: 'just kidding' },
 {
 from: 'Ember',
 to: 'me',
 subject: 'I hate you Angular!',
 date: 'Dec 8',
 body: 'wassup dude' }
];

用这个:

$http.post("/Home/GetEmails").then(function(response) {
 $scope.emails = response.data;
});

最后,我们需要在 angular控制器 中添加 $http 作为参数,就像我们在 $scope 中所做的那样。 因此,你的控制器方法应该从以下位置进行更改:

EmailController($scope)

对此:

EmailController($scope, $http)

就是这样,如果你编译并运行这个,你应该看到你的电子邮件 List 更改。

一个下去一个去。 发送邮件会非常相似,主要区别是我们没有把任何数据传递给 GetEmails(),但是我们需要把发送给 sendEmail()的电子邮件传递给。

这个方法很简单。 所有服务器都将填充电子邮件的日期和字段并将信息发送回 Angular。 为了完成这个任务我们需要两个。 我们需要向 ASP.NET 控制器和 C# 类添加一个操作来保存数据 Angular 发送。

让我们从 C# 类开始。 它应该包含在JavaScript代码中找到的所有相同字段。 出于我们的目的,你可以将这个类放在任何地方。 为了简化事情并将所有代码放在一个地方,我将它作为一个嵌套类 inside 添加到控制器:

publicclass ComposeEmail
{
 publicstringfrom { get; set; }
 publicstring to { get; set; }
 publicstring subject { get; set; }
 publicstring date { get; set; }
 publicstring body { get; set; }
}

对于 ASP.NET 动作方法本身:

public ActionResult SendEmail(ComposeEmail composeEmail)
{
 composeEmail.from = "me";
 composeEmail.date = DateTime.Now.ToString("MMM d");
 return Json(composeEmail);
}

最后,来自 Angular的调用。 更改 sendEmail() 方法,方法如下:

$scope.sendEmail = function () {
 $scope.isComposePopupVisible = false;
 $scope.composeEmail.from = "me";
 $scope.composeEmail.date = new Date();
 $scope.sentEmails.splice(0, 0, $scope.composeEmail);
};

对此:

$scope.sendEmail = function () {
 $http.post("/Home/SendEmail", $scope.composeEmail).then(function (response) {
 $scope.isComposePopupVisible = false;
 $scope.composeEmail = response.data;
 $scope.sentEmails.splice(0, 0, $scope.composeEmail);
 });
};

就是这样如果现在运行代码,发送电子邮件并检查"已经发送"选项卡,就会看到日期。 如果单击打开该电子邮件,你将看到" from"字段已经填充。

这涵盖了AngularJS的要点以及创建简单功能web应用程序所需的一切。 在本系列中,你创建了一个带有多个屏幕的相当精细的界面,可以动态更新。 为了使它能够运行,你与后端服务器通信来完成工作。

我们只是在 scratching AngularJS可能的表面。