本文主要是介绍数据视图(AngularJS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
<!DOCTYPE html>
<html ng-app="home.controller"><head><meta charset="utf-8"><title>数据视图</title><link href="page/common/css/bootstrap.min.css" rel="stylesheet"><script src="page/common/js/angular.js"></script><script src="page/common/js/angular-animate.min.js"></script><script src="page/common/js/angular-route.min.js"></script><script src="page/common/js/ui-bootstrap-tpls.js"></script><script src="page/app/js/home-controller.js"></script><script src="page/app/js/dbview-controller.js"></script><script src="page/app/js/view-api.js"></script><style type="text/css">.login_header {background: url(./page/pictures/logo_idm.jpg) center left no-repeat;width: 100%;height: 101px;margin-left: 40px;}.spinner {left: 30% ;width: 60px;height: 60px;background-color: #67CF22;margin: 100px auto;-webkit-animation: rotateplane 1.2s infinite ease-in-out;animation: rotateplane 1.2s infinite ease-in-out;}@-webkit-keyframes rotateplane {0% { -webkit-transform: perspective(120px) }50% { -webkit-transform: perspective(120px) rotateY(180deg) }100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }}@keyframes rotateplane {0% {transform: perspective(120px) rotateX(0deg) rotateY(0deg);-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)} 50% {transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)} 100% {transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);}}</style></head><body><div class="login_header"></div><div><div class="col-xs-1"><ul class="nav nav-stacked"><li><a href="#/index">数据字典</a></li><li><a href="#/sqlanalysis">语义分析</a></li></ul></div><div class="col-xs-9"><div ng-view=""></div><br/><br/><br/><br/></div></div></body></html>
<div><div class="col-xs-5"><ul style="position:absolute; height:1200px; overflow-y:auto"><li ng-repeat="table in all_tables" ng-click="queryByTableName(table.table_name , table.comments)"> <a href>{{table.table_name}}<font size="3" color="red">({{table.comments}})</font></a></li> </ul></div><div class="col-xs-5" ><h1 ng-show="show_view_table"> {{current_table_name}}</h1><span class="label label-default" ng-show="show_view_table"> {{current_table_comments}} </span><br><br><table class="table table-striped" ng-show="show_view_table"> <tbody class="row pre-scrollable"> <tr> <th>字段</th> <th>描述</th> <th>类型</th> <th>可否为空</th> <th>长度</th> </tr> <tr ng-repeat="row in table_desc"> <td class="warning" ng-if="row.is_primarykey == 'Y' ">{{row.column_name}}</td> <td ng-if="row.is_primarykey != 'Y' ">{{row.column_name}}</td> <td>{{row.comments}}</td> <td>{{row.data_type}}</td> <td>{{row.nullable}}</td> <td>{{row.data_length}}</td> </tr> </tbody> </table> <div class="spinner" ng-show="is_loading"></div></div></div>
<div><div class="col-xs-6"><form novalidate><textarea rows="30" ng-model="sqltext" style="width:100%;background-color:#C7EDCC;color:#000000;font-size:5;"></textarea><button class="btn btn-primary btn-lg btn-block" ng-click="formatSql()">SQL格式化</button> <button class="btn btn-primary btn-lg btn-block" ng-click="sqlAnalysis()">SQL语义分析</button></form> </div><div class="col-xs-4" ><div class="spinner" ng-show="is_loading_sql_analysis"></div><pre style="width:2000px" ng-bind-html="sql_analysis_reslut | to_trusted" ng-hide="hide_sql_analysis_result"></pre></div>
</div>
var app = angular.module("home.controller" , ["ngRoute" , "dbview.controller"]) ; app.config(function ($routeProvider) { $routeProvider. when('/home', { templateUrl: './page/app/html/index.html', controller: 'dbViewCtrl' }). when('/index', { templateUrl: './page/app/html/index.html', controller: 'dbViewCtrl' }). when('/sqlanalysis', { templateUrl: './page/app/html/sqlanalysis.html', controller: 'dbViewCtrl' }). otherwise({ redirectTo: '/home' });
});
var app = angular.module("viewApi.service", []);
app.service("viewApiService", ['$http' , '$q' , function($http , $q){ this.queryAllTables = function(userName){ var deferred = $q.defer(); $http.get("api/queryAllTables") .success(function(data) { deferred.resolve(data); }) .error(function(data) { deferred.reject(data); }) ; return deferred.promise; } ; this.queryByTableName = function(tableName){ var deferred = $q.defer(); $http.get("api/queryByTableName?tableName=" + tableName) .success(function(data) { deferred.resolve(data); }) .error(function(data) { deferred.reject(data); }) ; return deferred.promise; } ; this.sqlAnalysis = function(sqltext){ var deferred = $q.defer(); $http.get("api/queryByTableName?tableName=" + tableName) .success(function(data) { deferred.resolve(data); }) .error(function(data) { deferred.reject(data); }) ; return deferred.promise; } ; }]);
var app = angular.module("dbview.controller", ["viewApi.service"]);app.controller("dbViewCtrl" , ["$scope", '$http', '$q', '$location' ,"viewApiService" , function($scope, $http, $q , $location , viewApiService) {console.log("hello idoc") ;$scope.show_view_table = false ;$scope.is_loading_sql_analysis = false ;$scope.current_table_name = "" ;$scope.hide_sql_analysis_result = true ;viewApiService.queryAllTables().then(function(data){ $scope.all_tables = data ; }, function(data) { $defer.resolve([]); }); $scope.queryByTableName = function(tableName , comments){ console.log(tableName) ;console.log(comments) ;$scope.current_table_name = tableName ;$scope.current_table_comments = comments ;$scope.is_loading = true ;$scope.show_view_table = false ;var deferred = $q.defer(); viewApiService.queryByTableName(tableName).then(function(data){ $scope.show_view_table = true ; $scope.is_loading = false ;$scope.table_desc = data ; }, function(data) { $defer.resolve([]); }); } ; $scope.sqlAnalysis = function(){$scope.hide_sql_analysis_result = true ;$scope.is_loading_sql_analysis = true ;$http({ method:'post', url:'api/sqlAnalysis', data:{sqltext: $scope.sqltext} }).success(function(req){console.log(req) ;$scope.sql_analysis_reslut = req ;$scope.is_loading_sql_analysis = false ;$scope.hide_sql_analysis_result = false ;}) };$scope.formatSql = function(){console.log($scope.sqltext) ;$http({ method:'post', url:'api/formatSql', data:{sqltext: $scope.sqltext} }).success(function(req){console.log(req) ;$scope.sqltext = req ;}) };}]);app.filter('to_trusted', ['$sce', function($sce){return function(text) {return $sce.trustAsHtml(text);};
}]);
package com.ceair.api;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class WebContorller {@RequestMapping(value = "home")public String homeWeb() {return "home";}}
package com.ceair.api;import java.util.List;
import java.util.Map;import javax.servlet.http.HttpServletRequest;import net.sf.jsqlparser.JSQLParserException;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;import com.alibaba.fastjson.JSONObject;
import com.ceair.model.ConstModel;
import com.ceair.service.SqlAnalysisService;
import com.ceair.service.ViewService;@Controller
@RequestMapping(value = "api")
public class ViewController {@Autowiredprivate ViewService viewService ;@Autowiredprivate SqlAnalysisService analysisService ; @RequestMapping(value = "queryByTableName")@ResponseBodypublic List<Map<String , String>> queryByTableName(@RequestParam(value = "tableName") String tableName) { return viewService.queryByTableName(tableName) ;}@RequestMapping(value = "queryAllTables")@ResponseBodypublic List<Map<String , String>> queryAllTables() { return viewService.queryAllTables() ;}@RequestMapping(value = "sqlAnalysis")@ResponseBodypublic String sqlAnalysis(@RequestBody JSONObject jsonObj) { String sqltext = jsonObj.getString("sqltext") ;try {return analysisService.analysis(sqltext) ;} catch (JSQLParserException e) {return ConstModel.ERROR ;}}@RequestMapping(value = "formatSql")@ResponseBodypublic String formatSql(HttpServletRequest request , @RequestBody JSONObject jsonObj) { String sqltext = jsonObj.getString("sqltext") ;try {return analysisService.formatSql(request , sqltext) ;} catch (Exception e) {return ConstModel.ERROR ;}}}
package com.ceair.model;public class ConstModel {public static String STATUS = "status" ;public static String YES = "yes" ;public static String NO = "no" ;public static String HAS_LOGIN = "has_login" ;public static String USER_NAME = "user_name" ;public static String ERROR = "ERROR!" ;
}
package com.ceair.service;import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;import javax.annotation.PostConstruct;import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;import com.ceair.utils.OracleDBHelper;@Service
public class ViewService {private static final Logger logger = Logger.getLogger(ViewService.class); public List<Map<String,String>> allTables ;public Map<String,String> tableDes = new HashMap<String, String>() ;public Map<String , List<Map<String , String>>> tableInfo = new HashMap<String, List<Map<String,String>>>() ;public Map<String , Map<String , String>> tableColumnsDesc = new HashMap<String, Map<String,String>>() ;@PostConstructpublic void init(){allTables = queryAllTables() ;}public List<Map<String , String>> queryByTableName(String tableName) { if(tableInfo != null && tableInfo.containsKey(tableName)){return tableInfo.get(tableName) ;}logger.info("from DB") ;String sqlPid = " select col.column_name "+" from user_constraints con, user_cons_columns col "+ " where con.constraint_name = col.constraint_name "+" and con.constraint_type='P' "+" and Lower(col.table_name) = '" + tableName.toLowerCase() + "' " ;Set<String> pids = new HashSet<String>() ;OracleDBHelper db = new OracleDBHelper(sqlPid); try { ResultSet ret = db.pst.executeQuery(); while(ret.next()) {pids.add(ret.getString("column_name")) ;}ret.close(); db.close(); } catch (SQLException e) { } List<Map<String , String>> result = new ArrayList<Map<String , String>>() ;String sql = "select t.table_name, t.column_name, c.DATA_TYPE, c.NULLABLE , c.DATA_LENGTH, t.comments " + " from USER_COL_COMMENTS t , USER_TAB_COLUMNS c " + " where c.column_name = t.column_name " + " and Lower(c.TABLE_NAME) = '" + tableName.toLowerCase() + "' " +" and c.TABLE_NAME = t.TABLE_NAME " ; Map<String , String> columns = new HashMap<String, String>() ;db = new OracleDBHelper(sql); try { ResultSet ret = db.pst.executeQuery(); while(ret.next()) {String table_name = ret.getString("table_name") ;String column_name = ret.getString("column_name") ;String DATA_TYPE = ret.getString("DATA_TYPE") ;String NULLABLE = ret.getString("NULLABLE") ;String DATA_LENGTH = ret.getString("DATA_LENGTH") ;String comments = ret.getString("comments") ;Map<String , String> row = new HashMap<String, String>() ; row.put("table_name", table_name) ;row.put("column_name", column_name) ;row.put("data_type", DATA_TYPE) ;row.put("nullable", NULLABLE) ;row.put("data_length", DATA_LENGTH) ;row.put("comments", comments) ;if(pids.contains(column_name)){row.put("is_primarykey", "Y") ;}else{row.put("is_primarykey", "N") ;}result.add(row) ;columns.put(column_name , comments) ;}ret.close(); db.close(); } catch (SQLException e) { } tableInfo.put(tableName, result) ;tableColumnsDesc.put(tableName, columns) ;Collections.sort(result , new Comparator<Map<String , String>>() {@Overridepublic int compare(Map<String, String> firsrt ,Map<String, String> second){if("Y".equals(firsrt.get("is_primarykey"))){return -1 ;} if("Y".equals(second.get("is_primarykey"))){return 1 ;} return firsrt.get("column_name").compareTo(second.get("column_name")) ;}});return result ;} public List<Map<String,String>> queryAllTables() { if((allTables != null) && (!allTables.isEmpty())){return allTables ;}logger.info("from DB") ;List<Map<String,String>> result = new ArrayList<Map<String,String>>() ;String sql = " select table_name,comments from user_tab_comments order by table_name asc " ;OracleDBHelper db = new OracleDBHelper(sql); try { ResultSet ret = db.pst.executeQuery(); while(ret.next()) {Map<String , String> row = new HashMap<String, String>() ; String table_name = ret.getString("table_name") ;String comments = ret.getString("comments") ;row.put("table_name", table_name) ;row.put("comments", comments) ;result.add(row) ;tableDes.put(table_name.toLowerCase(), comments) ;}ret.close(); db.close(); } catch (SQLException e) { } return result ;} public static void main(String[] args) throws IOException {ViewService api = new ViewService() ;
// List<Map<String , String>> reslut = api.queryByTableName("DOC_TICKET") ;List<Map<String , String>> reslut = api.queryAllTables() ;for(int i = 1 ; i <= reslut.size() ; i++){System.out.println(i + ":" + reslut.get(i-1)) ;}}}
package com.ceair.service;import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;import javax.servlet.http.HttpServletRequest;import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.util.TablesNamesFinder;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.alibaba.fastjson.JSONObject;@Service
public class SqlAnalysisService {@Autowired private ViewService viewService ;private class Node implements Comparable<Node>{String columes ;String desc ; Node(String columes , String desc ){this.columes = columes ;this.desc = desc ;}@Overridepublic int compareTo(Node other) {return Integer.compare(other.columes.length() , this.columes.length()) ;}}private String redFont(String text){return "<font color=\"red\">" + text + "</font>" ;} private String blueFont(String text){return "<font color=\"blue\">" + text + "</font>" ;}private String greenFont(String text){return "<strong><font color=\"green\">" + text + "</font></strong>" ;}public String analysis(String sqltext) throws JSQLParserException {sqltext = sqltext.replace("(", " ( ").replace(")", " ) ").replace("=", " = ").replace("\n", " \n ") ;Statement statement = CCJSqlParserUtil.parse(sqltext);Select selectStatement = (Select) statement;TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();List<String> tableList = tablesNamesFinder.getTableList(selectStatement);Set<String> tableSet = new HashSet<String>() ;Map<String , String> columnsDesc = new HashMap<String, String>() ; for(String tableName : tableList){tableSet.add(tableName) ;viewService.queryByTableName(tableName) ;columnsDesc.putAll(viewService.tableColumnsDesc.get(tableName)) ;}List<Node> nodes = new ArrayList<Node>() ;for(Map.Entry<String, String> kv : columnsDesc.entrySet()){nodes.add(new Node(kv.getKey(), kv.getValue())) ;}Collections.sort(nodes) ;StringBuilder build = new StringBuilder() ;String[] str = sqltext.split(" ") ;String father = "" ;for(int i = 0 ; i < str.length ; i++){if(str[i].contains("\n")){build.append(str[i] + " ") ;continue ;}if(tableSet.contains(str[i].trim())){str[i] = greenFont(str[i]) + redFont("[" + viewService.tableDes.get(str[i].trim().toLowerCase()) + "]") ;}else{if(! "as".equals(father)){for(Node node : nodes){if(str[i].trim().contains(node.columes)){str[i] = str[i].replace(node.columes, blueFont(node.columes) + redFont("[" + node.desc + "]")) ;break ;}}}}build.append(str[i] + " ") ;father = str[i].toLowerCase() ;}sqltext = build.toString().replace(" ( ", "(").replace(" ) ", ")").replace(" = ", "=") ;return sqltext ; }public String formatSql(HttpServletRequest request , String sqltext) throws Exception{String path = request.getSession().getServletContext().getRealPath("/"); System.out.println(path) ;String pythonApiPath = path + "pythonfile"+ File.separator + "sqlformate.py" ; System.out.println(pythonApiPath) ;String jsontext = "" ;try {Process pr = Runtime.getRuntime().exec(new String[] { "python", pythonApiPath , sqltext});BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream(), "utf-8"));String line ;while ((line = in.readLine()) != null) {jsontext += line + "\n" ;}in.close();pr.waitFor();} catch (Exception e) {throw new Exception() ;} JSONObject json = JSONObject.parseObject(jsontext) ;String sql_text = json.getString("sql_text") ; return sql_text ;}}
import json
import sysimport sqlparseif __name__ == '__main__':sql_text = sys.argv[1]sql_text = sqlparse.format(sql_text , reindent=True) ;result = {"sql_text":sql_text}print(json.dumps(result))
package com.ceair.utils;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class OracleDBHelper { public static final String url = PropertiesUtils.getProperty("idoc_url") ;public static final String user = PropertiesUtils.getProperty("idoc_user") ;public static final String password = PropertiesUtils.getProperty("idoc_password") ;public Connection conn = null; public PreparedStatement pst = null; public OracleDBHelper(String sql) { try { Class.forName("oracle.jdbc.driver.OracleDriver");//指定连接类型 conn = DriverManager.getConnection(url, user, password);//获取连接 pst = conn.prepareStatement(sql);//准备执行语句 } catch (Exception e) { e.printStackTrace(); } } public void close() { try { this.conn.close(); this.pst.close(); } catch (SQLException e) { e.printStackTrace(); } }
}
package com.ceair.utils;import java.util.HashMap;
import java.util.Map;
import java.util.Properties;import org.apache.log4j.Logger;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;public class PropertiesUtils extends PropertyPlaceholderConfigurer { private static final Logger logger = Logger.getLogger(PropertiesUtils.class); private static Map<String, String> map = new HashMap<String, String>() ; @Override protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) { super.processProperties(beanFactory, props) ; for (Object key : props.keySet()) { String keyStr = key.toString() ; String value = props.getProperty(keyStr) ; logger.info(key+"="+value);map.put(keyStr, value) ; } } public static String getProperty(String key) { return map.get(key); } }
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"id="WebApp_ID" version="3.0"><context-param><param-name>log4jConfigLocation</param-name><param-value>classpath:log4j.properties</param-value></context-param><context-param><param-name>log4jRefreshInterval</param-name><param-value>6000</param-value></context-param><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.js</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.csv</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.json</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.html</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.css</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.jpg</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.png</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.PNG</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.woff</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.woff2</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.ttf</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.eot</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.svg</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.ico</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.gif</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.pdf</url-pattern></servlet-mapping><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"><mvc:annotation-driven /><mvc:default-servlet-handler /><context:component-scan base-package="com.ceair" /><beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="page/app/html/" /><property name="suffix" value=".html" /></bean><mvc:annotation-driven><mvc:message-converters register-defaults="true"><beanclass="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"p:supportedMediaTypes="*/*" /></mvc:message-converters></mvc:annotation-driven><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /><bean id="propertyConfigurer" class="com.ceair.utils.PropertiesUtils"><property name="locations"><list><value> classpath:app.properties </value></list></property></bean></beans>
这篇关于数据视图(AngularJS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!