2013-08-09 11 views
6

Czy istnieje funkcja Underscore.js, która może odwzorować jeden obiekt na inny obiekt, na podstawie właściwości innego obiektu?Underscore.js obiekt-obiekt mapper?

(niby jak AutoMapper działa w .NET.)

Na przykład:

var objectA = { 'name': 'Jonathan', 'city': 'Sydney' }; 
var objectB = { 'name': 'Jonathan Conway', 'city': 'Sydney', 'errors': [] } 

_.mapperMethod(objectB); 

=> { 'name': 'Jonathan Conway', 'city': 'Sydney' }; 

Odpowiedz

10

Ewentualnie _.extend():

_.extend(objectA, objectB); 

console.log(objectA); 
// { 'name': 'Jonathan Conway', 'city': 'Sydney', 'errors': [] } 

Jeśli nie chcesz odebrać dodatkowe klawisze można go używać z _.keys() i _.pick():

var keys = _.keys(objectA); 
_.extend(objectA, _.pick(objectB, keys)); 

console.log(objectA); 
// { 'name': 'Jonathan Conway', 'city': 'Sydney' } 
+0

Dzięki, że działa idealnie! Połączyłem oba połączenia w jedną funkcję: extendPick. https://gist.github.com/jonathanconway/6193584 – Jonathan

+0

Jak wywołać funkcję 'extendPick'? –

+1

@IlyaPalkin Jeśli masz na myśli sedno jonathanconway, to po prostu '_.extendPick (objectA, objectB);'. Zmodyfikuje i zwróci 'objectA'. –

2
Below is my auto mapper 

    var sourceObj, desObj; 
    var map: function (source, destination) { 
        var desKeys = _.keys(destination), functions; 
        _.extend(destination, _.pick(source, desKeys)); 
        sourceObj = source; 
        desObj = destination; 

        functions = { 
         forMember: function (sourceKey, desKey) { 
          var keys = sourceKey.split('.'), sourceValue = sourceObj, index = 0; 

          // incase sourceKey is a nested object like objectA.Value 
          if (keys.length) { 
           while (index < keys.length) { 
            sourceValue = sourceValue[keys[index]]; 
            index++; 
           } 
           desObj[desKey] = sourceValue; 
          } 
          else { 
           desObj[desKey] = sourceObj[sourceKey]; 
          } 

          return functions; 
         } 
        }; 
        return functions; 
       } 

var mapList: function (listSource, listDestination) { 
        _.each(listDestination, function(destination, i){ 
         var source = listSource[i]; 
         map(source,destination); 
         }); 

        functions = { 
         forMember: function (sourceKey, desKey) { 
          _.each(listDestination, function(destination, i){ 
           var source = listSource[i]; 
           map(source,destination) 
           .forMember(sourceKey, desKey); 
          }); 

          return functions; 
         } 
        }; 
        return functions; 
       } 


and how to use it 

    var source = { 
    Name: 'Nguyen Tran', 
    Age: '30', 
    Address: { 
       Street: '121 Le Van Viet', 
       City: 'HCM' 
       } 
    }; 

    var destination = { 
     Name: 'test', 
     age: '25', 
     Street: '', 
     City: '' 
    }; 
     autoMapper.map(source, destination) 
        .forMember('Age', 'age') 
        .forMember('Address.Street', 'Street') 
        .forMember('Address.City', 'City') 

Hope this work for you. 
+0

Jak pracujesz z tablicami? – Naor

+0

@Naor: Przepraszam, że odpowiedziałem tak długo. zaktualizowałem mapowanie, obsługuje również mapowanie tablicowe. Mam nadzieję, że to działa dla ciebie. Dzięki –

0

W ciągu ostatnich kilku miesięcy, udało mi się stworzyć całkiem kompletny portu biblioteki AutoMapper dla maszynopis/JavaScript: AutoMapperTS. Port ma - wśród wielu innych funkcji - obsługuje spłaszczanie/zagnieżdżanie i asynchroniczne odwzorowania.

Więcej informacji na temat biblioteki AutoMapperTS, w tym w jaki sposób zainstalować go za pomocą NPM i altana, proszę zapoznać się z biblioteki na GitHub: http://b.ldmn.nl/AutoMapperTS

+0

Twoja praca jest dobra, ale pisanie jest problematyczne. Jeśli możesz poprawić obsługę pisania, wiele osób skorzysta z tego. –

+0

Czy próbowałeś użyć pliku definicji TypeScript (jest on częścią pakietu NPM)? Czym dokładnie jest problem, o którym mówisz? – DotBert