Ember.js用户手册.docx_第1页
Ember.js用户手册.docx_第2页
Ember.js用户手册.docx_第3页
Ember.js用户手册.docx_第4页
Ember.js用户手册.docx_第5页
已阅读5页,还剩72页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Ember.js用户手册王为坤目录修订页2目录- 1 -第一章 开始- 5 -1.1.静态应用- 5 -1.2.动态应用- 8 -1.3.服务端交互- 10 -第二章 概念- 13 -2.1核心概念- 13 -2.1.1应用- 14 -2.1.2路由器- 14 -2.1.3模型- 14 -2.1.4模版- 14 -2.1.5控制器- 15 -2.1.6视图- 15 -2.2命名约定- 15 -2.2.1.应用- 15 -2.2.2.简单路由- 16 -2.2.3.动态参数- 18 -2.2.4.默认的路由器,控制器和模版- 18 -2.2.5.嵌套路由- 19 -2.2.6.索引路由- 19 -第三章 详解- 22 -3.1应用- 22 -3.2路由器- 22 -3.3.1配置路由器- 22 -3.3.2定义路由- 23 -3.3.3资源- 24 -3.3.4动态参数- 25 -3.3.5嵌套资源- 26 -3.3.6指定模型- 26 -3.3.7设置控制器- 27 -3.3.8渲染模版- 28 -3.3.9重定向- 29 -3.3.10指定url类型- 30 -3.3模型- 31 -3.4.1定义Store- 31 -3.4.2定义模型- 32 -3.4.3查找记录- 33 -3.4.4修改属性- 34 -3.4.5模型生命周期- 35 -3.4.6REST 连接器- 36 -3.4模版- 41 -3.4.1介绍- 41 -3.4.2条件- 43 -3.4.3遍历- 43 -3.4.4绑定属性- 44 -3.4.5绑定样式- 45 -3.4.6链接- 47 -3.4.7事件- 49 -3.4.8视图- 51 -3.4.9非绑定表达式- 51 -3.4.10自定义模版标记- 51 -3.5控制器- 52 -3.5.1ObjectController- 52 -3.5.2ArrayController- 53 -3.5.3依赖关系- 54 -3.6视图- 55 -3.6.1定义视图类- 56 -3.6.2在模版中嵌入视图- 56 -3.6.3事件处理- 59 -3.6.4修饰器- 60 -3.6.5自定义视图元素- 62 -3.6.6内置视图- 64 -3.6.7手动管理视图层级- 64 -3.7对象模型- 66 -3.7.1.类和实例- 66 -3.7.2.计算属性- 68 -3.7.3.观察者- 70 -3.7.4.绑定- 71 -3.7.5.枚举- 73 -第四章 组件- 74 -4.1.介绍- 74 -4.2.组件列表- 74 -附录1 事件名对照表- 77 -第一章 开始我会从一个简单的例子开始,围绕这个例子,把框架的核心概念进行基本的讲解。然后后面会有每个需要关注的点的详细解说。1.1. 静态应用首先,我们看例子,经典的hello World。 简单示例Hello,World! 这是一个简单示例这是一个可运行的最简单的应用了。运行它就可以看到屏幕上的输出。下面,我们来看代码。直接看body里的部分。前面4行是引入框架库文件,接下来就到重点了window.UserMgr = Ember.Application.create();这行创建了一个应用。什么是应用?简单的说,应用就是整个程序,其他的东西属于应用。所以创建一个应用就是程序的入口了。继续往下Hello,World! 这是一个简单ember.js示例这是一个模版应用的主模版。模版是就是需要显示用户界面。它是HTML加模版语言。模版语言上例中还没用到,后面再说。应用的主模版是在应用启动时自动调用的模版。下面我们来加入路由器在单个页面中展示多个页面的效果。我们先简单理解路由器,它负责根据访问地址调用相应的模版(就像我们的web服务器根据访问地址调用不同的html页面一样)。window.UserMgr = Ember.Application.create();/路由UserMgr.Router.map(function() this.resource(users, path: / , function() this.route(new);););其实在应用创建的时候,路由器就已经创建好了。我们只是进行路由的配置。上例中,我们配置了两个路由,users和users.new。resource是一个特殊的路由,它是路由组,是一组路由的父路由。路由的path表示的是url。省略path表示path等于路由名。上面路由配置的意思是,当我们访问地址为/的时候,调用users路由,当访问/new的时候调用users.new路由。现在我们来增加两个新的模版,注意这里的模版比上面的应用模版多了data-template-name,这是定义模版名字,应用模版的模版名是application,是可以省略的。模版名需要与路由名对应,users路由对应的users模版,users.new路由对应users/new模版。这是用户列表页面这是新建用户页面我们期望在访问/的时候显示users模版的内容。刷新页面,没有变化。为啥呢?我们忘记告诉框架,新的模版要在哪里显示。默认的,通过路由调用的模版会显示在父模版的outlet处。users的父模版是应用主模版。那么我们就修改一下应用主模版Hello,World! 这是一个简单示例outlet然后刷新页面。看到结果了users/new模版的父模版users里也加上outlet。这是用户列表页面outlet然后我们在当前地址后面加上#/new。上面我们其实访问的是#/。路由匹配的url也是这个#后面的地址。看到结果如下1.2. 动态应用上面的的内容都是静态的,下面我们开始加点动态的内容。先来一个动态的用户列表。首先改写users模版,模版中用到#each来遍历。#each中用到了controller。它是users路由关联的控制器,控制器用来给模版提供数据以及处理模版中的事件,这里系统会自动生成,我们先跳过它。#each u in u.sex/eachoutlet有模版了。然后提供数据给模版,开始实现users路由。我们实现user路由对应的路由类就可以了,系统会自动调用。按照命名约定,users路由对应路由类UserMgr.UsersRoute。UserMgr.UsersRoute = Ember.Route.extend(model: function() return Ember.Object.create(name:张三,sex:男),Ember.Object.create(name:李四,sex:女),Ember.Object.create(name:王麻子,sex:男););实现了路由的model方法,路由的modal方法作用是:通过模型像服务端请求数据。我们先跳过模型的介绍,以及与服务端的交互,直接返回一个数组。框架会自动创建users的控制器,并讲返回的数组赋值给控制器。我们在模版中就可以直接使用了。现在看看结果。现在我们添加一个按钮用来跳转到新建用户页面。修改users模版添加#each u in u.sex/eachoutlet模版中用到action gotoAddUser来给按钮添加点击事件。默认是会调用控制器的gotoAddUser方法。我们加上控制器代码。按照命名规则,users路由对应的控制器是UserMgr.UsersController。UserMgr.UsersController = Ember.ArrayController.extend(gotoAddUser: function()this.target.transitionTo(users.new););gotoAddUser方法通过this.target访问到路由器,然后调用路由器的transitionTo方法实现了跳转到user.new路由。刷新页面,点击添加按钮就可以看到效果。1.3. 服务端交互现在我们加上与服务器交互的部分。这里开始,我们需要把我们的页面放到web服务器上运行啦。服务器上的服务我会用静态的文本文件代替。首先,定义一个模型,下面的User模型描述了User对象的属性name和sex。UserMgr.User = DS.Model.extend(name: DS.attr(string),sex: DS.attr(string);定义一个storeUserMgr.Store = DS.Store.extend(revision: 11);然后修改users路由中获取数据的方式UserMgr.UsersRoute = Ember.Route.extend(model: function() return UserMgr.User.find(););刷新页面,我们会发现,应用向 http:/localhost/users 这个地址发起了请求。因为我的demo没有放在根路径,所以我们配置一下连接器。UserMgr.Store = DS.Store.extend(revision: 11,adapter: UserMgr.RESTAdapter);UserMgr.RESTAdapter = DS.RESTAdapter.extend(namespace: jsframe/ember-sample1/apps/demo/data);使用store的adapter属性指定一个连接器,该连接器继承自RESTAdapter,设置namespace。这表示,生成的请求链接是域名+namespace+模型的小写复数形式。demo访问地址是 http:/localhost/jsframe/ember-sample1/apps/demo/,用户列表数据访问地址是http:/localhost/jsframe/ember-sample1/apps/demo/data/users/。用户列表数据为一个json文件,按照命名规则,返回的数组需要用users(模型的小写复数形式)包裹,内容如下users: id: 1,name: 张三,sex: 男,id: 2,name: 李四,sex: 男,id: 3,name: 王麻子,sex: 女,id: 4,name: 小飞飞,sex: 女刷新页面,就可以看到结果例子到这里就结束了。大家可以根据后面的内容,尝试改动例子来深入的理解。第二章 概念2.1 核心概念Ember中有几个核心概念,应用、路由器、模版、视图、控制器、模型路由器路由路由路由模版视图控制器模型模版视图控制器模型模版视图控制器模型界面模块界面模块界面模块应用应用包含一个路由器、和N个界面模块。路由器包含N个路由。界面模块是一个虚拟的概念,表示界面上的一小块,每个界面模块由一个模版,一个控制器,一个模型组成。界面模块间模型是可以公用的,模版、控制器理论上可以公用,一般不会公用。模版与视图是相互作用的,模版中可以直接调用视图,视图也可以包含一个模版,它们一起组成了界面。应用应用是一个全局的命名空间对象。你应用程序中所有的类,对象都应该定义为应用的成员。应用还会负责为视图代理事件到ducument;自动渲染应用模版;自动创建路由器。2.1.1 路由器路由器是一个负责管理应用状态的对象。每个应用状态就由一个路由表示。路由器管理了一组路由,路由负责将URL与模版、模型、控制器关联起来。当你的用户启动应用程序时,路由器将根据URL调用相应的路由,显示相应的模板,并为模板配对相应的模型对象。2.1.2 模型模型是一个存储持久化数据的对象。这些数据会被你的应用操作的,还会展示值给用户。这些数据通常是从服务器获取,当数据改变时,还会保存到服务器。通常,使用Ember Data将加载的数据转化成具有关系,计算属性的模型实例。2.1.3 模版模版是用来描述你的应用的用户界面的,它是用Handlebars 模版语言来写的。除了普通的HTML,模版还包含以下内容: 表达式,从控制器和模型中获取数据,并将数据替换成html内容。当数据改变时,会自动更新html内容。例如:firstName。 插座(Outlet),模版的占位符。当用户访问你的应用的时候,路由器会根据url将不同的模版插入到插座(outlet)中展示出来。在模版中使用outlet标签来添加一个插座(outlet)。 视图(View),负责处理用户事件。在模版中使用view标签来添加一个视图。2.1.4 控制器控制器是一个存储应用临时数据的对象。模版会连接控制器,并将当前存储的数据转换成HTML。控制器通常作为模型的代理,为模版提供数据。这种情况下,控制器传递模型的属性给模版,可以通过改变模型来改变展现结果。2.1.5 视图视图负责将原生事件转换成你的应用中的语义事件,并将事件发送到控制器。视图需要包含一个模版,也可以被嵌入模版中。例如,一个视图可能转换一个click事件成有意义的deleteItem事件,然后发送到控制器中。如果控制器没有实现deleteItem事件,则会发送到当前的路由中。2.2 命名约定框架没有使用写很多引用的方式来关联对象,而是通过命名约定,来关联路由器、控制器、模版。2.2.1. 应用当你的应用启动的时候,Ember会查找这些: App.ApplicationRoute App.ApplicationController application模版框架会渲染application模版为主模版。如果你定义了App.ApplicationController,框架会创建一个App.ApplicationController的实例,并将这个实例设置为 template 的控制器。也就是说,模版中的需要的数据会从这个控制器实例的属性中获取。如果你的应用定义了App.ApplicationRoute,在application模版渲染前,框架会先调用路由的钩子方法(model, setupController, renderTemplate)。这里是一个使用路由,控制器,模版的简单例子:12345678910App.ApplicationRoute = Ember.Route.extend( setupController: function(controller) / controller is the instance of ApplicationController controller.set(title, Hello world!); );App.ApplicationController = Ember.Controller.extend( appName: My First Example);1234appNametitle在框架的应用中,你只需要指定控制器类,框架会实例化他们,并将他们提供给模版。2.2.2. 简单路由每个路由都有一个以路由名字命名的路由、控制器、模版。让我们从一个简单的路由器开始:123App.Router.map(function() this.route(favorites););如果你导航到/favorites, 框架会查找这些: App.FavoritesRoute App.FavoritesController favorites模版框架会渲染favorites模版到application模版中的outlet,还会创建一个App.FavoritesController实例,并且设置为模版的控制器。如果你的应用定义了App.FavoritesRoute,框架会在模版渲染前,自动调用它。这跟上面应用中的步骤是一样的。对于App.FavoritesRoute,你可能需要实现model钩子方法去指定你的控制器将要传递给模版的模型实例。例如:123456App.FavoritesRoute = Ember.Route.extend( model: function() / the model is an Array of all of the posts return App.Post.find(); );在这个例子里,我们没有定义FavoritesController。因为这里的 model 方法返回了数组,框架会自动提供一个Ember.ArrayController的实例,该实例会将返回的数组作为它的model属性。相比于直接使用模型,使用ArrayController有两点主要好处: 任何时候,当你替换了一个控制器的模型,你不需要通知视图。 控制器可以提供额外的计算属性,或者保存不属于模型层的视图的临时状态。 这样使得视图、控制器、模型完全分离。模版可以遍历控制器中的一个元素:12345#each controller title/each2.2.3. 动态参数如果一个路由使用了动态参数,这个路由的model将基于这个参数的值。考虑这个路由器定义:123App.Router.map(function() this.resource(post, path: /posts/:post_id ););在这种情况下,这个路由的名字是post, 框架会查找这些: App.PostRoute App.PostController post模版你的路由的model方法传递参数:post_id到模型里。serialize方法转换模型对象到URL参数中。 (例如:计算一个模型的链接的时候).123456789App.PostRoute = Ember.Route.extend( model: function(params) return App.Post.find(params.post_id); , serialize: function(post) return post_id: post.get(id) ; );因为这种模式很常见,所以路由提供了默认的处理。 如果你的动态参数以_id结束,model方法会转换参数post_id的第一部分为应用的命名空间下的一个模型类(post变成App.Post)。然后调用类的find方法,并传入动态参数值。 默认的serialize方法会用模型的id属性值给动态参数赋值。2.2.4. 默认的路由器,控制器和模版如果你没有定义post路由的路由类 (App.PostRoute),框架仍然会使用App.PostController的数据实例渲染post模版。如果你没有定义控制器 (App.PostController),Ember 会自动创建一个,数据则是路由的model方法返回的模型。如果模型是一个数组,该控制器继承自ArrayController,否则,继承自ObjectController。如果你没有定义post模版, 框架不会渲染任何东西!2.2.5. 嵌套路由你可以在resource下嵌套路由。123456App.Router.map(function() this.resource(posts, function() / the posts route this.route(favorites); / the posts.favorites route this.resource(post); / the post route ););路由、控制器、模版的名字以资源名开头。对于post这种内嵌的资源, 路由的名字是App.PostRoute,控制器的名字是App.PostController,模版名字是post.当你内嵌一个路由到资源中,路由名被加到 资源名和一个.后。这里是上面的路由器中定义的每个路由转换后的名字:Route NameControllerRouteTemplatepostsPostsControllerPostsRoutepostsposts.favoritesPostsFavoritesControllerPostsFavoritesRouteposts/favoritespostPostControllerPostRoutepost按一般的规则,资源名用名词,路由用形容词 (favorites) 或 动词(edit)。这能确保内嵌不会创造出很长的怪异的名字, 但是要避免相同的形容词和动词冲突。2.2.6. 索引路由无论在哪一级的路由(包括顶层路由),框架会自动给/路径创建一个index路由。例如,你写了下面一个简单的路由器:123App.Router.map(function() this.route(favorites););它等价于:1234App.Router.map(function() this.route(index, path: / ); this.route(favorites););如果用户访问/,框架会查找下面这些: App.IndexRoute App.IndexController index模版index模版会渲染到应用模版的outlet。如果用户导航到/favorites,框架会使用favorites模版替换index模版。如下的内嵌路由器:12345App.Router.map(function() this.resource(posts, function() this.route(favorites); ););等价于:1234567App.Router.map(function() this.route(index, path: / ); this.resource(posts, function() this.route(index, path: / ); this.route(favorites); ););如果用户导航到/posts,当前路由会是posts.index。框架会查找以下这些名字的对象: App.PostsIndexRoute App.PostsIndexController posts/index模版首先,posts模版会渲染到应用模版的outlet。然后,posts/index模版会渲染到posts模版的outlet。如果用户又导航到/posts/favorites,框架会替换posts模版的outlet中的内容为posts/favorites模版。第三章 详解3.1 应用创建一个Ember 应用的第一步就是实例化Ember.Applicationwindow.App = Ember.Application.create();这里的应用命名App, 它是可以随意取的。 实例化出一个应用对象是很重要的,原因如下: 它是你应用的命名空间,你应用下的所有类都要定义为这个对象的属性(例如:App.PostsView 和 App.PostsController)。这能预防全局命名冲突。 它给document添加了事件监听,并且负责发送事件到你的视图。 它自动渲染application模版-其他模版将渲染在它里面的最顶层模版。 它自动创建了路由器,并且基于URL进行路由调配。3.2 路由器用户与你的应用交互,会产生很多不同的状态。框架提供了管理这些状态的有用的工具。在框架中,应用中每个可能的状态都体现在URL上,并且由路由器负责管理这些状态。路由器下有一组路由,每个路由对应一个状态,也就是一个URL。当你的应用启动,路由器负责显示模版,加载数据和设置应用状态。它通过匹配当前的URL到你定义的路由来完成工作。3.3.1 配置路由器App.Router.map(function() this.route(about, path: /about ); this.route(favorites, path: /favs ););当用户访问 / ,框架会渲染 index 模版。访问 /about 渲染 about 模版,访问 /favs 渲染favorites 模版。当path与路由名相同,就可以省略path。上例等价于App.Router.map(function() this.route(about); this.route(favorites, path: /favs ););在你的模版里,可以通过linkTo标记指定路由名在路由间导航。(/路径的名字是index)#linkTo index/linkTo #linkTo aboutAbout/linkTo #linkTo favoritesFavorites/linkTo关于linkTo的详细请看3.4.5。3.3.2 定义路由你可以通过创建一个Ember.Route的子类来自定义路由的行为。例如,定制当用户访问 / 时的行为,创建App.IndexRouteApp.IndexRoute = Ember.Route.extend( setupController: function(controller) / Set the IndexControllers title controller.set(title, My App); );IndexController是index模版的首选上下文。现在你已经设置了title,你可以在模版中使用title(如果你没有定义App.IndexController,框架会自动创建一个。)框架会根据传给this.route的名字来自动计算路由、控制器、模版的名字。URLRoute NameControllerRouteTemplate/indexIndexControllerIndexRouteindex/aboutaboutAboutControllerAboutRouteabout/favsfavoritesFavoritesControllerFavoritesRoutefavorites3.3.3 资源你可以用resources来定义一个路由组。App.Router.map(function() this.resource(posts, path: /posts , function() this.route(new); ););和this.route一样。path与资源名一样的时候,可以省略path,所以上面的等价于App.Router.map(function() this.resource(posts, function() this.route(new); ););这个路由器会创建四个路由URLRoute NameControllerRouteTemplate/indexIndexControllerIndexRouteindexN/Aposts1PostsControllerPostsRouteposts/postsposts.indexPostsControllerPostsIndexControllerPostsRoutePostsIndexRoutepostsposts/index/posts/newposts.newPostsControllerPostsNewControllerPostsRoutePostsNewRoutepostsposts/new1跳转或者链接到posts的行为会被自动重定向到posts.index注意:如果你配置一个资源但是不提供一个function,那么框架不会创建resource.index路由。这种情况下,/resource会使用ResourceRoute,ResourceController和resource模版。这时this.resource等价于this.route资源中内嵌的路由的全名要把资源名加在它的名字前(posts.new 不是new)。如果你要跳转到一个路由(无论是通过transitionTo或者#linkTo),确保使用全名(posts.new 不是new)。访问 / 时,跟上面将的规则一样,会渲染 index 模版。访问 /posts 就有些不一样了。首先会渲染 posts 模版。然后会渲染 posts/index 模版到posts模版的outlet中。访问 posts/new 也会先渲染 posts 模版。然后会渲染 posts/new 模版到posts模版的outlet中。注意:你应该用名词表示一个资源,资源内的route用形容词或者动词修饰这个名词。3.3.4 动态参数动态参数以“:”开头,后面跟着参数名。App.Router.map(function() this.resource(posts); this.resource(post, path: /post/:post_id ););App.PostRoute = Ember.Route.extend( model: function(params) return App.Post.find(params.post_id); , serialize: function(post) return post_id: post.get(id) ; );你的路由的model方法传递参数:post_id到模型里。serialize方法转换模型对象到URL参数中。 (例如:计算一个模型的链接的时候).因为这种模式很常见,所以路由提供了默认的处理。 如果你的动态参数以_id结束,model方法会转换参数post_id的第一部分为应用的命名空间下的一个模型类(post变成App.Post)。然后调用类的find方法,并传入动态参数值。 默认的serialize方法会用模型的id属性值给动态参数赋值。所以上面的serialize方法可以省略。3.3.5 嵌套资源你不能在路由中嵌套路由,但是可以在资源中嵌套资源。App.Router.map(function() this.resource(post, path: /post/:post_id , function() this.route(edit); this.resource(comments, function() this.route(new); ); ););这个路由器生成以下路由:URLRoute NameControllerRouteTemplate/indexApp.IndexControllerApp.IndexRouteindexN/ApostApp.PostControllerApp.PostRoutepost/post/:post_id2post.indexApp.PostIndexControllerApp.PostIndexRoutepost/index/post/:post_id/editpost.editApp.PostEditControllerApp.PostEditRoutepost/editN/AcommentsApp.CommentsControllerApp.CommentsRoutecomments/post/:post_id/commentscomments.indexApp.CommentsIndexControllerApp.CommentsIndexRoutecomments/index/post/:post_id/comments/newcomments.newApp.CommentsNewControllerApp.CommentsNewRoutecomments/new3.3.6 指定模型如果你没有动态参数,你需要自己实现model方法,指定使用哪个模型关联匹配的url。App.Router.map(function() this.resource(posts););App.PostsRoute = Ember.Route.extend( model: function() return App.Post.find(); );如果用到动态参数,你会想要通过参数来获取模型。App.Router.map(function() this.resource(post, path: /posts/:post_id ););App.PostRoute = Ember.Route.extend( model: function(params) return App.Post.find(params.post_id); );因为这种模式太常见,上面的model方法就是默认行为。例如,你的动态参数是post_id,框架会使用_前的post为模型也就是App.Post。除非你重写model方法,否则路由会自动返回App.Post.find(params.post_id)。3.3.7 设置控制器在框架中,模版从控制器中获取信息并显示出来。框架中有两个内置的控制器,Ember.ObjectController 和 Ember.ArrayController。它们很好用。它们代理模型的属性,并且有自己的额外的属性,最终传递给模版。在setupController方法中,设置控制器的content属性来代理模型。App.Router.map(function() this.resource(post, path: /posts/:post_id ););App.PostRoute = Ember.Route.extend( setupController: function(controller, model) controller.set(content, model); );setupController方法接收两个参数,第一个是该路由关联的控制器,第二个是model方法返回的模型。上面的例子中,PostRoute的关联控制器是App.PostController的实例。setupController方法的默认行为就是上面代码。所以你可以省略上面的setupController。如果你不只是想操作关联的控制器,可以用controllerFor方法。App.PostRoute = Ember.Route.extend( setupController: function(controller, model) this.controllerFor(topPost).set(content, model); );3.3.8 渲染模版路由的一个重要工作就是渲染指定的模版到屏幕。默认的,会渲染关联的模版到最近的父模版的outlet中,并使用关联的控制器。App.PostsRoute = Ember.Route.extend( renderTemplate: function(controller, model) this.render(); );包含全部的参数的代码如下App.PostsRoute = Ember.Ro

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论