说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

实例剖析:如何用Foundation For Apps创建完美Web应用

HTML文档下载 WORD文档下载 PDF文档下载
不久前,Zurb推出了单页面App框架Foundation for Apps,其与Foundation 5密切相关。它试图提供一种开发Web应用既快速又简单的方法,本文通过实战案例,分析了该框架的使用方法,是一份综合性指南。

【编者按】本文是Smashing Magazine中《Creating A Complete Web App In Foundation For Apps》一文的简译内容,详细描述了用Foundation For Apps创建完美Web应用“星球大战知识库”的全过程。

Foundation for Apps是Zurb推出的一个新型单页面App框架,与Foundation 5(也称为Foundation for Sites,一个广泛使用的前端框架)密切相关。它围绕AngularJS和弹性网格框架构建而成。它试图让Web应用的开发过程既快速又简单,开发者可以快速开始编写针对应用的独一无二的代码,而非模板文件。

Foundation for Apps于2014年年底发布,尚未被广泛使用,因此有关如何使用这一框架的优质信息源比较少。本文将作为一篇综合指南,对构建一个功能性移动App的全过程进行介绍。文中的技术细节是为客户打造应用程序的基础,本教程也可看作是对AngularJS和单页应用在更广阔范围下如何使用的有力说明。

根据今年后半年即将上映的一部新电影,我们将构建一个“星球大战知识库”。它是一个使用RESTful API、缓存和Foundation for Apps、AngularJS多个特性的响应式Web应用程序。

想要直接跳到干货?

  • DEMO观看;
  • 在GitHub上查看;
  • 文件下载。

入门指南

快速浏览官方文档,其对设计样式进行了很好解释,但并没有对应用程序功能进行详细说明。将这一卓越的AngularJS文档放在手边,并牢牢记住Foundation for Apps提供了一些标准之外的服务,AngularJS的一些功能可能无法直接使用。同样要注意,AngularJS 和Foundation for Apps与生俱来就不太适用于对SEO有要求的App,因为大部分内容需要通过AJAX加载。

我们的应用程序将从Star Wars API(在SWAPI中)中提取数据。先浏览下SWAPI文档,了解其中的数据和结构。为了简单起见,我们的应用程序将建立在这一结构之上。

首先,我们要安装Foundation for Apps并创建项目。请确保您已经安装了Ruby(OS X已默认安装)和Node.js,然后遵循Foundation for Apps详细文档中的四个步骤。即便你以前没使用过命令行,这个过程也十分简单。当你完成该些步骤后,在浏览器中输入“http://localhost:8080/#!/”,即可看到应用程序的默认主页。


Foundation for Apps的默认主页 (浏览大图)

让我们熟悉一下项目里的文件和文件夹。

应用程序根目录中唯一需要我们注意的文件是gulpfile.js,它向Gulp构建过程发送指令,让其为应用启动服务。Gulp是一个构建系统,与Grunt非常相似。稍后,如果我们想添加一些AngularJS模块或插件时,可以通过JavaScript、CSS文件(引用了这些模块或插件)来更新该Gulp文件。

 Cient文件夹里能找到其它我们关注的文件夹:

  •  clients/assets/js/app.js,应用程序的控制器、指令和自定义过滤器在该文件中;
  •  应用程序的所有SCSS文件都存放在clients/assets/scss里;
  •  clients/index.html是应用程序的主页模板;
  • 在clients/templates/中可以找到所有页面的模板,其中大多数还未创建。

构建模板和主页面

让我们开始构建吧!index.html页面无法很好地满足实际应用的需要,所以首先修改该页面。我们针对小尺寸屏幕增加了Off-Canvas菜单、切换按钮及漂亮的淡入淡出效果(利用Foundation for Apps中“Motion UI”的类样式实现)。你可以直接从Github repository中index.html文件里复制这些代码。

在_settings.scss文件中添加一些SCSS变量来设置颜色、字体和断点:

  $primary-color: #000;$secondary-color: #ffe306;$body-background: $secondary-color;$breakpoints: (  small: rem-calc(600),  medium: rem-calc(900),  large: rem-calc(1200),  xlarge: rem-calc(1440),  xxlarge: rem-calc(1920),);$h1-font-size: rem-calc(80);$body-font-family: "brandon-grotesque", Helvetica, Arial, sans-serif;$header-font-family: "flood-std", Helvetica, sans-serif;

现在我们要加点儿料美化一下app.scss。你可以直接参考Github repository中的该文件。

接下来,快速重写默认的home.html文件,该文件在clients/templates/ 目录下,此目录列出了所有要建页面的链接菜单:

---name: homeurl: /---<div class="grid-content">  <h1>Star Wars Compendium</h1>  <p class="lead">Foundation for Apps using Star Wars API</p>  <hr>  <ul class="home-list">    <li><a ui-sref="films">Films</a></li>    <li><a ui-sref="species">Species</a></li>    <li><a ui-sref="planets">Planets</a></li>    <li><a ui-sref="people">People</a></li>    <li><a ui-sref="starships">Starships</a></li>    <li><a ui-sref="vehicles">Vehicles</a></li>  </ul></div>

 我们的模板现在看起来已经相当别致——不再是千篇一律的Foundation。


 我们的模板——已经有了些看头(浏览大图)

创建电影列表

我们正大步向前。在templates文件夹中,为首个子页面创建模板文件:films.html。把下面小段代码复制粘贴到顶端:

---name: filmsurl: /films/:id?p=controller: FilmsCtrl---

 这段代码告诉了我们三件事:

  1. Films为该页面名称,在指向该页面的所有链接中可使用;
  2.  URL将有两个可选参数:id(根据我们的数据生成的影片ID)和p(所在电影列表中的页码数);
  3.  我们将使用自定义AngularJS控制器FilmsCtrl,而不是Foundation for Apps自动创建的默认空白控制器。

因为我们要使用自己的控制器,接下来就要在app.js里创建一个(控制器)。浏览下面的控制器,它将被用于电影列表和单个影片页面。你能看到,该控制器保持追踪URL参数,定位我们所在的结果页面,从外部API里获取所需信息(是电影列表还是单个影片的细节,取决于URL参数),并使用$scope变量将这些信息返回到页面视图里。等angular.module声明关闭后,再把它添加到app.js中。

controller('FilmsCtrl',  ["$scope", "$state", "$http",function($scope, $state, $http){  // Grab URL parameters - this is unique to FFA, not standard for  // AngularJS. Ensure $state is included in your dependencies list  // in the controller definition above.  $scope.id = ($state.params.id || '');  $scope.page = ($state.params.p || 1);  // If we're on the first page or page is set to default  if ($scope.page == 1) {    if ($scope.id != '') {      // We've got a URL parameter, so let's get the single entity's      // data from our data source      $http.get("http://swapi.co/api/"+'films'+"/"+$scope.id,          {cache: true })        .success(function(data) {          // If the request succeeds, assign our data to the 'film'          // variable, passed to our page through $scope          $scope['film'] = data;        })    } else {      // There is no ID, so we'll show a list of all films.      // We're on page 1, so the next page is 2.      $http.get("http://swapi.co/api/"+'films'+"/", { cache: true })        .success(function(data) {          $scope['films'] = data;          if (data['next']) $scope.nextPage = 2;        });    }  } else {    // Once again, there is no ID, so we'll show a list of all films.    // If there's a next page, let's add it. Otherwise just add the    // previous page button.    $http.get("http://swapi.co/api/"+'films'+"/?page="+$scope.page,      { cache: true }).success(function(data) {        $scope['films'] = data;        if (data['next']) $scope.nextPage = 1*$scope.page + 1;      });      $scope.prevPage = 1*$scope.page - 1;  }  return $scope;}])  // Ensure you don't end in a semicolon, because more     // actions are to follow.

保存完app.js后,你需要通过终端(Control+ C用来取消操作,然后再运行foundation-app watch)重启服务,以保证应用程序包含该新模板(files.html)文件,而该文件中都创建了新控制器(app.js)。

就是这样,我们有了一个功能完整的控制器,它能从外部RESTful API资源中获取数据,将结果缓存至浏览器的session中,并把数据返回到视图页面中。

再次打开films.html,开始构建可以访问的数据视图。首先增加展示电影列表的视图内容。我们可以访问所有添加到$scope变量中的属性,无需加前缀$scope,如本例中的films、prevPage和nextPage。在模板现有内容下添加如下代码:

<div class="grid-content films" ng-show="films">  <a class="button pagination"    ng-show="prevPage"    ui-sref="films({ p: prevPage })">    Back to Page {{prevPage}}  </a>  <div class="grid-content shrink">    <ul class="menu-bar vertical">      <li ng-repeat="film in films.results">        {{film.title}}      </li>    </ul>  </div>  <a class="button pagination"    ng-show="nextPage"    ui-sref="films({ p: nextPage })">    To Page {{nextPage}}  </a></div>

非常明显!如果有多页的数据,我们就会得到一个电影名称列表和页码数。但这些数据还没有特别明显的用途,接下来我们把影片名称换成了影片页面所对应的链接。

我们计划将影片ID作为URL的id参数。我们已访问影片的url属性,正好包含了影片ID,即最后一个斜杠前的最后一个参数。然而,我们如何才能从访问的URL中获取唯一的ID?AngularJS通过自定义过滤器使其变得很容易。把{{film.title}}封装在一个链接里,为该连接添加ui-sref属性(用来设置内部链接),其值为包含定制过滤器的film.url数据,示例代码如下:

<a ui-sref="films({ id:( film.url | lastdir ), p:'' })">  {{film.title | capitalize}}</a>

现在页面仍处于不可用状态,因为应用无法识别lastdir和capitalize过滤器是什么。我们需要在app.js文件中控制器的后面定义这些过滤器:

.filter('capitalize', function() {  // Send the results of this manipulating function  // back to the view.  return function (input) {    // If input exists, replace the first letter of    // each word with its capital equivalent.    return (!!input) ? input.replace(/([^\W_]+[^\s-]*) */g,      function(txt){return txt.charAt(0).toUpperCase() +        txt.substr(1)}) : '';  }}).filter('lastdir', function () {  // Send the results of this manipulating function  // back to the view.  return function (input) {    // Simple JavaScript to split and slice like a fine chef.    return (!!input) ? input.split('/').slice(-2, -1)[0] : '';  }})

 搞定!现在我们有了电影列表,每部电影都能链接到各自的电影页面。


电影链表:不知为什么,总对前面部分有些担心(浏览大图)。

然而,点击链接后进入的却是一个空白页,因为films.html还只是个完整的电影信息列表,还没有被构建成可以显示具体电影信息的页面。展示电影细节是我们下一步的工作。

展示一部电影的细节

FilmsCtrl控制器里的$scope.film变量(与$scope['film']相同)中已包含了单个影片页面所需的所有数据。所以,重新使用films.html,并增添另一部分内容,该内容只有在单个file变量被设置时才可见。接着我们会为<dl>中的每组<dt>和<dd>中设置一个键值对(key-value pair)。同时要记住film中某些字段,如characters在数组中有多个值,需通过ng-repeat嵌套一一显示出来。为了把每个演员与该演员的页面连接起来,我们将使用在影片列表中用到的同样方法:用lastdir过滤器,根据他/她/它的ID,链接至每个演员对应的people页面。

<div class="grid-content film"  ng-show="film" ng-init="crawl = 'false'">  <h1>Episode {{film.episode_id | uppercase}}:     {{film.title}}</h1>  <hr>  <dl>    <dt>Opening Crawl</dt>    <dd ng-class="{'crawl':crawl === true}"       ng-click="crawl === true ? crawl = false : crawl = true">      {{film.opening_crawl}}</dd>    <dt>Director</dt>    <dd>{{film.director | capitalize}}</dd>    <dt>Producer</dt>    <dd>{{film.producer | capitalize}}</dd>    <dt>Characters</dt>    <dd ng-repeat="character in film.characters"      ui-sref="people({ id:(character | lastdir), p:''})">      {{character}}    </dd>  </dl></div>

可是,当我们浏览每部电影的条目时,演员列表仅显示了与该演员相关的URL,而不是演员的名字。


这些人物到底是谁?这样可不行(观察大图)。

我们需要用演员名字来替换这些URL文本,但是我们还没有这些关键性数据。或许在我们获取film的URL中会包含演员的名字。我们再次打开app.js,并增加getProp命令。

.directive("getProp", ['$http', '$filter', function($http, $filter) {  return {    // All we're going to display is the scope's property variable.    template: "{{property}}",    scope: {      // Rather than hard-coding 'name' as in 'person.name', we may need      // to access 'title' in some instances, so we use a variable (prop) instead.      prop: "=",      // This is the swapi.co URL that we pass to the directive.      url: "="    },    link: function(scope, element, attrs) {      // Make our 'capitalize' filter usable here      var capitalize = $filter('capitalize');      // Make an http request for the 'url' variable passed to this directive      $http.get(scope.url, { cache: true }).then(function(result) {        // Get the 'prop' property of our returned data so we can use it in the template.        scope.property = capitalize(result.data[scope.prop]);      }, function(err) {        // If there's an error, just return 'Unknown'.        scope.property = "Unknown";      });    }  }}])

getProp每次从$http.get返回的数据中返回单一属性,从中我们可以提取出所需要的属性。为了使用该指令,需要把它添加到ng-repeat循环内,就像这样:

<span get-prop prop="'name'" url="character">{{character}}</span>

很好!现在我们有了每个演员的名称及对应页面的链接,而不只是一个不明所以的URL。数据字段的其它数据添加到file页面后,这个页面就算完成了(Github Repository中查看films.html的其余代码)。


这样就好多了(观看大图)

为了重用而重构代码

通过SWAPI文档和应用程序其余部分的规划,我们清楚地看到,所有其它页面的控制器与这个极为相似,只是在获取的数据分类上有些许不同。

根据这一想法,我们把file控制器中代码移至称为genericController的功能函数,并放在app.js最后一个右括号的前面。同时还需要用变量multiple(五个实例)来替换字符串里的'films',用single(一个实例)替换'film',因为它们代表了每个页面实体的复数和单数形式。这正好让我们DRY,是一种易于读取和理解、具有可重用性的代码。

现在我们可以利用新的genericController函数(包含变量数据的复数和单数形式)新建并调用FilmsCtrl控制器,像参数那样:

.controller('FilmsCtrl', function($scope, $state, $http){  $scope = genericController($scope, $state, $http, 'films', 'film');})

很棒!我们有一个可重用的控制器,它能够提取任何给定页面所需的数据,并在一定的样式呈现出来!现在可以在FilmsCtrl后以相同的方式创建其他页面的控制器。

.controller('SpeciesCtrl', function($scope, $state, $http){  $scope = genericController($scope, $state, $http, 'species', 'specie');}).controller('PlanetsCtrl', function($scope, $state, $http){  $scope = genericController($scope, $state, $http, 'planets', 'planet');}).controller('PeopleCtrl', function($scope, $state, $http){  $scope = genericController($scope, $state, $http, 'people', 'person');}).controller('StarshipsCtrl', function($scope, $state, $http){  $scope = genericController($scope, $state, $http, 'starships', 'starship');})

接下来,采用与创建films.html相同的方式,为planets、species、people、starships和vehicles创建模板HTML文件。创建时要参考SWAPI文档里每类数据中的各个字段。

瞧!现在所有页面都显示出正确的数据并相互关联!


完整的应用程序(观看大图)

结束语

应用程序完成了!我们的应用DEMO(下文有链接)由Aerobatic托管,专门针对前端Web应用。在资源库里,你会看到我们增加了一些特殊选项,以利用Aerobatic API网关,该网关设置了一个代理,可以缓存服务器上被请求的API数据。在没有缓存的情况下,该应用即要进行延迟限制又要尽情请求数限制(SWAPI对每个域的请求数量有限制,跟其他APIs一样),因为我们的数据不经常变化,所以在第一次加载之后,服务器缓存使得一切变得非常高速。因为我们限制了onload请求和图像(数量),第一次加载速度较慢也可以接受,而且,在每个加载页面上,为了使应用速度更快,标题菜单会留在该页面上。

在DEMO和资源库里,你能看到我们在详细页面中添加了另一个API调用,它通过Google自定义搜索在Wookieepedia和StarWars.com中抓取每个实体的图像URI。因此,现在每个详细页面上都显示了动态且相关性极高的图像。

看看下面的演示,或者仔细分析隐藏部分和特定Foundation技巧的源代码,或者把仓库下载下来,然后在本地构建并改进它。

  • Star Wars Compendium,Foundation for Apps DEMO展示;
  • Star Wars Compendium Using Foundation for Apps,GitHub上;
  • 源文件下载(ZIP)。

原文链接:Creating A Complete Web App In Foundation For Apps

欢迎加入CSDN前端交流群:218126086,进行前端技术交流。 

黑帽大会演讲中国第一人:从攻到防,从白帽黑客到创业者 15个步骤创立技术公司,并收获千万用户(完结) CTO容易犯的三大错误 谷歌艺术计划:互联网能否取代真实的博物馆? Hadoop技术沙龙:Hortonworks技术研发总监展望Hadoop 2.0 Marissa Mayer:雅虎月活跃用户增长了20%达8亿 移动用户3.5亿 气死偷车贼:脑电波防盗技术,让偷车贼无计可施 TIOBE 2013年9月编程语言排行榜:Transact-SQL首次进入前十 前Oracle总裁Charles Phillips:商业软件领域的“乔布斯” 留住你的用户:8款第三方移动推送服务 人气最旺:主流移动应用创建工具大合集(一) 不要强迫用户注册,请让他们先试用产品 Eve:基于Python的REST API框架 想扩展你的数据库吗?那么先了解一下I/O 白帽黑客将现场爆料Android系统及框架漏洞 9月13日:程序员节,一起来过节吧! 欲与Siri、Google Now比高低:微软开始打造个人助理Cortana 【开源专访】禅道创始人王春生:覆盖项目全周期,回归管理的本质 携程无线创业者大赛成功落幕 梁建章为头名“快展”颁20万奖金 Bug报告:小角色,大用处! iOS开发者必备: 五大编程类工具 多核优化软件MCx释放EMC VNX闪存潜能 手把手教学:详解HTML5移动开发框架PhoneJS 快速学习新技术的几条建议 研发周报:Angular.js or Ember.js 谁将成为Web开发的新宠? 10款免费且开源的项目管理工具 Greg Pass:拯救Twitter的无名英雄 Cassandra杀回数据库排行Top 10,及需求Java 7的2.0版本 安全专家王清将揭秘“大数据时代的大安全” BrainSpace:跟传统搜索说再见 艾普网络的OpenStack实践 系统重装,SQL 6.5只剩下几个data目录下的dat文件,请问怎么才能把数据完全恢复? 客户端调试sql server存储过程 兄弟我想换工作,还企盼网友推荐(看在我对java版热心参与,请版主保留几天) 如何配置jConnect连接Sybase数据库?需要安装jdk吗? 如何在模块中编写一个函数,对数据库进行增,删,修改操作? a 请问各位DirectDraw是做什么的?最好能详细谈谈他的前景?谢谢! 我的win2000server在域中,被以域中Administrator进入,结果我的机子以域用户进入后,机子的系统关机选项变为不可用,以域中Administrato b/s应用程序怎样限制它只能安装在某一台电脑上? FORM中,如何通过 ODBC 访问 Foxpro的 dbf 数据文件(在线等待)? 如何判断连接服务器的sql数据库成功与否?在线等待高手解答! applet waiting online 程序员招聘(西安) 怎样让我的对话框程序实现全屏显示急急急1。。。 我的用法是否正确 有本事的就进来 JSP+JDBC环境中如何配置jConnect连接Sybase数据库?需要安装jdk吗? 急,高分求解Font问题 我编写了一个读写COOKIE的公用函数在我的工程中使用,老不通过,麻烦大哥们帮我诊断诊断 请问怎样获取托盘窗体的句柄??(给一百分) 请帮帮忙,如何调用dtswiz.dll 如何用BDE Administrator设置数据库别名(不用ODBC)访问Oracle数据库。高分相送! 对不起,我知道这个问题很简单,但是我一直没有搞出来,您能告诉我吗?datagrid中进行insert,delete,update操作? 寻求eVC用ADO操作cbd数据库的代码。 两个关于枚举类的问题 问用过struts的朋友一个问题,给100分! huffan交流系数表在C中如何表示?????? 线程问题~~~ 有哪位知道在 Windows 2000 下 锁定计算机时应用程序可以得到什么消息啊? 急!!关于数据的导入导出!! Cells不被VB支持吗? 获取字段类型 如何将DataGrid1中的数据打印出来, 如何使程序自动修改CEdit中的文字? 请问在.NET类库中有这样的类吗? 如何知道某个表格被锁 求助capboy等网络视频播放高手!!! 菜鸟问题:在VC中用ALTER TABLE指令需要什么头文件? 请高手帮忙,感觉难度很高 大家做GUI时有什么好用又免费的日期控件呢? 在javabean中用sql server2000的jdbc驱动连不起数据库! 添加图片到数据库中,奇怪现象! 如果我已经得到了一个DOM树, 我第一次运行HTML HELP时,new怎么会是无效的? 我的 程序在调用FORM.ACTION的用法不正确。能告诉我怎样用它 怎幺样实现一对主从表的数据库基本操作?用ADOQuery连接SQL2000. 有关统计打印的问题 一个关于用VB调用C++builder编写的DLL文件,DLL的API函数中存在函数指针。请各位高手给点意见! 大专生如何考研?(up有分) ★★ 为高兴而送分 ★★ 关于打印的问题,请各位帮忙 舟曲泥石流、5.12地震、玉树地震、还有一些地方的山洪,这意味着什么难道地球不行了吗,世界末日真的会不会到来 冲压弯头与热压弯头区别 井下放炮时,人距放炮点的安全距离是多少? K粉是什么?有什么成分?为什么能使人幻觉?求正解(带依据)吸食K粉对身体有何害?它究竟是什么?为什么它能让人产生幻觉?既然是软性毒品为什么禁不严? 在什么世纪,中国就发明了算盘这种计算工具 哪些科学家提高了时间的计量精度 K粉的危害到底有多大?K粉为什么那么容易上瘾?K粉的成分是什么? 身边不少朋友为了体验K粉的感觉,都上瘾K粉的危害到底有多大?K粉为什么那么容易上瘾?K粉的成分是什么?身边不少朋友为了体 将少量浓溴水滴入苯酚溶液中,有白色沉淀.这句话对吗?`到底是什么原因啊? 如何提高分光光度计检定的准确度? 哪些药物会含有氧化镁的成分 用稀溴水滴入苯酚溶液中制备2,4,6-三溴苯酚 错在哪里? 如何对地质灾害点进行勘察? 去疼片类药物 都含有什么成分 三溴苯酚是沉淀,二溴苯酚是否会沉淀?一溴哪? 地质灾害勘查与矿山地质勘查的区别是什么? 氯胺酮一般以盐酸盐形式存在,盐酸氯胺酮为( )结晶性粉末.( 酸碱盐中沉淀都有啥 啥颜色 啥状态 相关方程式如:Cu(OH)2为蓝色絮状沉淀 2NaOH+CuCO3=Na2CO3+Cu(OH)2 请问胰岛素冷藏温度 用什么冷藏胰岛素最好?请问大家胰岛素冷藏温度是多少,有糖友告诉我说胰岛素冷藏温度很低,温度高了可能会变质,然后医生也是这么说,但他们都没有告诉我胰岛素具体 分析下列汉字 的音节结构“远,窄,伟,英,凉,日,郡,困,柳,谢. 谁能给我酸碱盐溶解性表的俗称,沉淀颜色望老师作答,常考的有哪几个,怎么考法 胰岛素存放温度未开封的胰岛素(诺和)在冰箱冷藏时,由于冰箱出现故障,温度经常在2度到10度之间波动,有天清晨还达到了0度,估计0度的时间至少有5个小时,请问在这种温度环境下,会不会影 为什么高炉炼铁的时候生铁出口低于炉渣出口? 一般厕所产生的沼气在什么时候会引发爆炸(在厕所吸烟)? 煤矿安全规程对轨道运输的规定 除了汉语还有什么语言是象形文字?哪些语言使用代码或字母 简述样本回归函数与总体回归函数的区别 煤矿安全规程由多少条 英语翻译 为什么能用样本回归函数代表总体回归函数急 粗糙水平桌面上有一质量为m的铜质矩形线圈.当一竖直放置的条形磁铁从线圈中线AB正上方等高快速经过时,若线圈始终不动,则关于线圈受到的支持力FN及在水平方向运动趋势的正确判断是A 我想找一些词语但是不知道去哪里找,像一些希腊,拉丁语这样的翻译成中文,比如,”乌托邦“就是希腊词根翻译过来的,类似这种词我去哪里找? 函数回归一位 什么意思 如图所示,一条形磁铁竖直放在桌面上,一闭合圆线圈从其正上方某处,保持水平由静止下落,最后套上条形磁铁落到桌面上,该过程中( )A.线圈内产生大小、方向都不变的电流B.线圈内产生 组成词语 酸碱盐中什么遇到什么会有白色沉淀或者特殊反映 精子在水里会干?或者如果跟着水进入阴道会是卵子受孕? 一段时间后清理沼气池为什么发生过沼气爆炸 什么是船舶建造测量与精度管理,怎样实行精度管理? 地质灾害治理资质需要年检吗 沼气池中能产生很多沼气,可是气体不能燃烧,为什么?原来产生的气体能燃烧,最近的气不能点燃.希望具体回答. 高精度位置控制怎么测量呢? 哪里出具"不具有地质灾害治理监理单位资质的证明" 汉字与中国心的答案 在测量电压的操作中怎样提高测量结果的准确度? 为什么示差分光光度法可以提高测定的准确度? 求《汉字与中国心》的答案 甲烷分解成?甲烷分解成C2H2和H2还是C和H2,还是什么呢? 提高装配时的测量检验精度的方法有哪些? 神府洗煤厂洗煤絮凝剂,洗煤聚丙烯酰胺,洗煤聚丙烯酰胺絮凝剂,洗煤专用絮凝剂,这个产品,在神府哪里有卖 甲烷多少度分解 测量中 什么方式来提高观测值得精度? 柳林洗煤絮凝剂哪里有卖的,就是洗煤聚丙烯酰胺 甲烷的分解反应? 胰岛素的最佳储藏温度是多少? 什么是岭回归分析法? 洗煤厂介质粉 柴油 仲辛醇 絮凝剂 通常用量,按吨原煤的量洗煤厂 介质粉 柴油 仲辛醇 絮凝剂 通常用量,按吨原煤的量.一般用量范围 甲烷能分解吗最好写上化学反应方程式 浙江江西局地可能会有地质灾害说,是山洪是泥石流还是地震海啸呀? 厕所口全部盖住时间久了会产生沼气吗? 甲烷的分解反应有哪些越多越好
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘