jquery map

프로그램/js 2015.03.27 17:01

기본 array를 새로운 array로 mapping 하는 함수.


공식홈에서는 이렇게 가이드를 하고 있다.

  • jQuery.map( array, callback )

    • array
      Type: Array
      The Array to translate.
    • callback
      Type: FunctionObject elementOfArray, Integer indexInArray ) => Object
      The function to process each item against. The first argument to the function is the array item, the second argument is the index in array The function can return any value. A returned array will be flattened into the resulting array. Within the function, this refers to the global (window) object.
  • version added: 1.6jQuery.map( object, callback )

    • object
      Type: Object
      The Object to translate.
    • callback
      Type: FunctionObject propertyOfObject, String key ) => Object
      The function to process each item against. The first argument to the function is the value; the second argument is the key of the object property. The function can return any value to add to the array. A returned array will be flattened into the resulting array. Within the function, this refers to the global (window) object.

이를 설명하면 객체나 배열을 callback function의 첫 번째 인자로 주고  index or key의 두번째 인자를 활용하여  새로운 배열을 만들어 낼 수 있다. 


예를 들어 ..


var arr = [ "a", "b", "c", "d", "e" ];

arr = jQuery.map( arr, function( n, i ) {
return ( n.toUpperCase() + i );
});

이렇게 연산을 하면 리턴 배열은 

A0, B1, C2, D3, E4

이러한 결과 값을 가지게 되는 것이다.

'프로그램 > js' 카테고리의 다른 글

ajax와 인코딩문제  (0) 2015.03.27
javascript object 개념.  (0) 2015.03.27
jquery map  (0) 2015.03.27
slice()를 이용한 array copy  (0) 2015.03.27
jquery autocomplete  (0) 2015.02.22
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

slice 메소드는 

보통은 array.slice(start index, end index)를 이용하여 원하는 array만 얻고자할 때 쓰이는 메소드인데

array.slice(0)으로 하면 0번 인덱스 부터 끝까지 복사하게 되어 배열 전체를 복사하는 결과를 가져 올 수 있다.

$.map과 성격이 유사하고 혼용해서 쓰면 되겠다.

'프로그램 > js' 카테고리의 다른 글

ajax와 인코딩문제  (0) 2015.03.27
javascript object 개념.  (0) 2015.03.27
jquery map  (0) 2015.03.27
slice()를 이용한 array copy  (0) 2015.03.27
jquery autocomplete  (0) 2015.02.22
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

node.js의 환경에서 mvc 패턴을 구현하다 보면 module.exports와 exports를 자주 접하게 된다.

그 차이에 대해 알아보자.


아래 코드를 보자. 

1
2
3
4
5
6
7
8
9
10
// greetings.js
// var exports = module.exports = {};
         
exports.sayHelloInEnglish = function() {
  return "HELLO";
};
    
exports.sayHelloInSpanish = function() {
  return "Hola";
};

In the code above, we could have replaced exports with module.exports and achieved the same result. If this seems confusing, remember that exports and module.exports reference the same object.

위의 설명처럼 exports는 개개의 function마다 적용되고 결국 module.exports와 결과는 같다.

This is the current value of module.exports:

1
2
3
4
5
6
7
8
9
module.exports = {
  sayHelloInEnglish: function() {
    return "HELLO";
  },
        
  sayHelloInSpanish: function() {
    return "Hola";
  }
};

위 코드와 같이 module.exports는 여러 function을 묶어서 정의하게 된다.


지금 껏 node.js를 사용해오면서 require()를 쓸 때 내부 원리를 모르고 단순히 모듈을 import 하였는데, require()도 module.export 방식을 이용해서 module을 import 하는 것 이었다.

var require = function(path) {
 
  // ...
 
  return module.exports;
};

위와 같은 방식이다.



블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

autocomplete  - 텍스트 입력창에 글자를 입력하면 recommend text 를 serve 해주는 것.


중요한 부분이 source 부분인데 recommend text 배열이라고 할 수 있다. 공식홈에서는 이렇게 가이드를 하고 있다


source Type: Array or String or FunctionObject request, Function response( Object data ) )

Default: none; must be specified
Defines the data to use, must be specified.

Independent of the variant you use, the label is always treated as text. If you want the label to be treated as html you can use Scott González' html extension. The demos all focus on different variations of the sourceoption - look for one that matches your use case, and check out the code.

label 이라는 key가 text로 취급된다. source 옵션은 3가지가 있다. 

Multiple types supported:

  • Array: An array can be used for local data. There are two supported formats:
    • An array of strings: [ "Choice1", "Choice2" ]
    • An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ]
    The label property is displayed in the suggestion menu. The value will be inserted into the input element when a user selects an item. If just one property is specified, it will be used for both, e.g., if you provide only value properties, the value will also be used as the label.

우선 array는 string의 모임으로 구성 될 수도 있고 label key와 value 키를 가진 객체의 모임으로 구성될 수도 있다.
라벨 속성은 recommend 되는 텍스트이고 value는 눌렀을때 input에 입력되는 값이다. 만약 이렇게 key를 주지 않고 그냥 단어의 나열로 구성하면 두 속성을 모두 사용 하게 된다. 

  • String: When a string is used, the Autocomplete plugin expects that string to point to a URL resource that will return JSON data. It can be on the same host or on a different one (must provide JSONP). The Autocomplete plugin does not filter the results, instead a query string is added with a term field, which the server-side script should use for filtering the results. For example, if the source option is set to "http://example.com" and the user types foo, a GET request would be made to http://example.com?term=foo. The data itself can be in the same format as the local data described above.
  • Function: The third variation, a callback, provides the most flexibility and can be used to connect any data source to Autocomplete. The callback gets two arguments:
    • request object, with a single term property, which refers to the value currently in the text input. For example, if the user enters "new yo" in a city field, the Autocomplete term will equal "new yo".
    • response callback, which expects a single argument: the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data. It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.

    When filtering data locally, you can make use of the built-in $.ui.autocomplete.escapeRegex function. It'll take a single string argument and escape all regex characters, making the result safe to pass to new RegExp().


ajax를 이용하여 source를 구성할 때 function을 많이 쓴다.

request object를 이용해 http post로 input text를 서버에 전송한다. 이때 서버에서 input text는 term property로 구분된다.

예를 들어 node.js에서는 req.body.term 으로 받을 수 있다.

response object는 user에게 suggest할 data object이다. 이 data object는 request object에서 post로 보낸 provied term에 의해 filter된다. 


그럼 ajax를 이용한 예제를 보겠다 .


$('#country_name').autocomplete({
		      	source: function( request, response ) {
		      		$.ajax({
		      			url : 'ajax.php',
		      			dataType: "json",
						data: {
						   name_startsWith: request.term,
						   type: 'country'
						},
						 success: function( data ) {
							 response( $.map( data, function( item ) {
								return {
									label: item,
									value: item
								}
							}));
						}
		      		});
		      	},
		      	autoFocus: true,
		      	minLength: 0      	
		      });

위와 같이 보낼 때 data에는 key값을 사용자가 직접 정해서 server로 보내고 있다.

이때 그냥 request를 보내게 되면 term키를 이용하여 서버에서 input text를 받아볼 수 있다.

success 할 경우 data object를 server에서 받아 $.map을 이용하여 label과 value를 직접 mapping 해주고 있다.


서버단 코드를 보겠다.


<?php
require_once 'config.php';

if($_GET['type'] == 'country'){
	$result = mysql_query("SELECT name FROM country where name LIKE '".strtoupper($_GET['name_startsWith'])."%'");	
	$data = array();
	while ($row = mysql_fetch_array($result)) {
		array_push($data, $row['name']);	
	}	
	echo json_encode($data);
}

?>

db 에서 LiKE를 이용하여 input keyword가 들어간 name을 추출하여 array로 만든뒤에 json으로 클라이언트에 보내고 있다..


필자는 서버단 코드를 database에 직접 접근 하지 않고 초기에 db를 한번만 접근하여 받아온 데이터를 redis store에 저장한 뒤 이에 접근 하는 방식으로 구현해보려고 하고있다. 

'프로그램 > js' 카테고리의 다른 글

ajax와 인코딩문제  (0) 2015.03.27
javascript object 개념.  (0) 2015.03.27
jquery map  (0) 2015.03.27
slice()를 이용한 array copy  (0) 2015.03.27
jquery autocomplete  (0) 2015.02.22
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

1. swig

node.js 의 기본 template 모듈은 ejs와 jade를 많이 사용한다.

ejs는 html 형식에 javascript가 embedding된 형식이라서 쉽게 익힐 수 있다.

하지만 template 상속을 지원하지 않는 단점이 있다.


jade는 html태그 형식이 완전히 바뀌어 익히는 데 조금 어려움이 있지만 

다양한 api를 제공하는 장점이 있다.


node.js swig 모델은 위의 두 모델의 장점만을 살린 모델이라고 할 수 있겠다.

template engine으로 html을 사용하며 다양한 api를 지원한다.


extends, import ,include...등등을 응용할 수 있다. 

http://paularmstrong.github.io/swig 을 참조.


2. request 

node.js는 server-side language 이다. 

보통 request를 받아서 처리하는 데, 다른 외부 서버에 request를 하는 경우가 있을 수 있다.

이럴 때 request 모듈을 사용하면 유용하다.

https://www.npmjs.com/package/request 을 참조


3. xml-mapping

xml 데이터 형식을 json으로 바꾸거나 다른 형식으로 바꾸어 주는 module이다.


4. iconv

encoding 형식을 변경해준다.

euc-kr 에서 utf8로 변경하기 위해 사용했다.


5. crypto 

비밀번호 암호화를 제공해주는 모듈이다.

api가 약간 복잡하여(?) 현재 bcrypt-nodejs를 쓰고 있지만,

node.js 공식 api에도 소개되어 있는 module인 만큼 꼭 써봐야 하겠다.


6. view-helper

보통 web project는 mvc pattern을 이용하여 프로젝트를 많이 한다.

view-helper 모듈은 view 단에서 reqest 객체를 접근하게 할 수 있는 모듈이다.

이외에 다른 여러가지 기능도 제공한다.


7. 내장 모듈 util

shallow copy를 위해서 내장 모듈 util를 사용하였다.

ex) var something = extend(기존내용,추가할내용);




블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

모듈 path 관리 기법.

https://gist.github.com/branneman/8048520

http://dogfeet.github.io/articles/2012/nodejs-modules.html

참고..


수많은 기법중 재미있는 모듈을 발견해서 이 방법으로 쓰기로 결정했다.


requirefrom 이라는 모듈이다. 


사용방법은 다음과 같다.


Simple usage anywhere in your node app:

requirefrom moudle을 호출하고..

    var lib = require('requirefrom')('lib');
    var myModule = lib('myModule');

For more complex usage, let's assume this example directory structure:

node_modules/
lib/
  components/
    framework/
      veiws/
        login.js
        signup.js
      models/
        user/
          index.js
  utlity/
    normalize/
      user.js
package.json

Any file in this project could then include these files with the following code:

node.js 프로젝트 내의 어떤파일도 아래 파일을 통해 require 할 수 있다.

이 rquirefrom이라는 모듈은 server.js(app.js)에서 선언한 뒤 글로벌하게 쓰이는 모듈이 아니다.

아래와 같이 따로 js 파일을 생성한뒤 이를 다시 require 시키는 것으로 보인다.

var
    requireFrom = require('requirefrom')
  , views = requireFrom('lib/components/framework/views/')
  , models = requireFrom('lib/components/framework/models/')
  , utility = requireFrom('lib/utility/')
 
  , loginForm = views('login.js')
  , signupForm = views('signup.js')
 
  , userModel = models('user')
 
  , normalizeUser = utility('normalize/user.js')



2015.02.13 수정 


위 방법은 해당파일에서만 적용되고 global 하게 적용이 안된다.

따라서 app.js server.js 에 다음과 같이 global function을 적용하여 쓰는것이 좋겠다.


global.controllers = function(name) {

    return require(__dirname + '/controllers/' + name);

}

global.models = function(name) {

    return require(__dirname + '/models/' + name);

}

global.config = function(name) {

    return require(__dirname + '/config/' + name);

}


이렇게 global function을 적용하고 나면 global 하게 다른파일에서도 사용가능하다.

또한, 이렇게 하면 require(....)이라고 명시하게 되던 모듈설정을 controllers(....), models(....), config(....)로 나타나게 되어 

positive effect of knowing characteristic of module 을 지닌다. 


블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요


좋은 포스팅이 있어 공유한다.

http://nodeqa.com/nodejs_ref/65

블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

지금 껏 나는 express의 본질인 connect middleware에 대해서 정확하게 이해하지 못하고 node.js를 사용해 온 것 같다.

미들웨어를 잘 설명하는 답변을 찾아 포스팅한다.

In most frameworks you get a request and you want to return a response. Because of the async nature of Node.js you run into problems with nested call backs if you are doing non trivial stuff. To keep this from happening Connect.js (Express.js is a layer on top of connect) has something that is called middleware which is a function with 2, 3 or 4 parameters.

대부분의 프레임워크에서는 request와 response가 있다. node.js의 비동기적인 특성 때문에 nested callback 문제에 부딪힐 수 있다(정확히 무슨말인지 이해가 안감)..

이를 위해서 Express는 미들웨어를 제공한다..

function (<err>, req, res, next) {}

Your Express.js app is a stack of these functions.

enter image description here

위의 그림이 명쾌하게 설명해주고 있다. request가 들어오면 built-in middleware가 실행되고(express는 네가지 미들웨어를 가진다. 

 

그 다음 router middleware가 실행된다. 이 시점에서 stack 에 있는 여러 routing function을 실행할 수 있다.  이렇게 한 스택에 있는 function을 사용하기 위해서 사용되는 메소드가 next()이다. 

The router is special, it's middleware that lets you execute one or more middleware for a certain url. So it's a stack inside a stack.

router는 특별하다. 그 것은 특정한 url에 들어온 요청을 한개이상의  middleware를 써서 실행하게 도와준다.  그렇기 때문에 stack안의 stack구조를 갖게된다.

So what does next do? Simple, it tells your app to run the next middleware. But what happens when you pass something to next? Express will abort the current stack and will run all the middleware that has 4 parameters.

그렇다면 next가 하는 역할은 무엇일까? 

expressjs 공식홈에 자세한 설명이 나와있다.


Middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application, commonly denoted by a variable named next. Middleware can:

  • Execute any code.
  • Make changes to the request and the response objects.
  • End the request-response cycle.
  • Call the next middleware in the stack.

If the current middleware does not end the request-response cycle, it must call next() to pass control to the next middleware, otherwise the request will be left hanging.

하나의 미들웨어는 request object 와 response object에 접근하는 function이다. req-res 사이클에서 next 미들웨어에도 접근할 수 있다. 이렇게 한 스택안에 여러가지의 routing middleware가 있을 때 next middleware에 접근할 수 있는 function이 next()이다... 

그렇다면 응용 예를 하나 보겠다.

app.param() 메소드를 통한 응용인데 ...

app.param()은 공식홈에서 이렇게 가이드를 하고 있다.

Add callback triggers to route paramters, where name is the name of the parameter or an array of them, and function is the callback function. The parameters of the callback function are the request object, the response object, the next middleware, and the value of the parameter, in that order.

For example, when :user is present in a route path, you may map user loadig logic to automatically provide req.user to the route, or perform validations on the parameter input.

첫번째 인자에 parameter를 주는데 이 파라미터가 next를 통해 다음 미들웨어를 호출할때 index로 쓰인다. 무슨 말인고 하면, 아래와 같이 app.param('user' 라고 user 파라미터를 주었다면 next를 통해 다음 라우팅 미들웨어를 실행할 때 user파라미터를 가지는 middleware가 실행되는 것이다.

app.param('user', function(req, res, next, id) {

  // try to get the user details from the User model and attach it to the request object
  User.find(id, function(err, user) {
    if (err) {
      next(err);
    } else if (user) {
      req.user = user;
      next();
    } else {
      next(new Error('failed to load user'));
    }
  });
});


따라서 아래와 같이 응용을 할 수 있게 되는데,  param을 통해 load 미들웨어를 실행하고 id를 파라미터로 가지는 미들웨어를 next()를 통해 선택적으로 실행한다. 즉 id 파라미터를 가지는 url로 들어오는 모든 요청은 aritcles.load 미들웨어를 거쳐 실행된다. 


app.param('id', articles.load); app.get('/articles', articles.index); app.get('/articles/new', auth.requiresLogin, articles.new); app.post('/articles', auth.requiresLogin, articles.create); app.get('/articles/:id', articles.show); app.get('/articles/:id/edit', articleAuth, articles.edit); app.put('/articles/:id', articleAuth, articles.update); app.delete('/articles/:id', articleAuth, articles.destroy);






블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요