2015-10-10 29 views

cevap

5

an explanation in the docs. Relay.Mutation alt sınıfını ve getFiles işlevini uygulayabilirsiniz.

Ayrıca, express-graphql, sunucu tarafında bunun nasıl işleneceği konusunda testlerinde an example sağlar.

+0

Çalışmayı başardı mı? paylaşabilir misin? –

+0

Yaptım. Bir şans elde ettiğimde bunu daha fazla ayrıntıyla güncelleyeceğim. –

10

Öncelikle ön uç bileşeninize Röle güncellemesini yazmanız gerekir. Bunun gibi :

onDrop: function(files) { 
    files.forEach((file)=> { 
    Relay.Store.commitUpdate(
     new AddImageMutation({ 
     file, 
     images: this.props.User, 
     }), 
     {onSuccess, onFailure} 
    ); 
    }); 
}, 

Sonra önyüz üzerinde mutasyon uygulayarak izleyin:

class AddImageMutation extends Relay.Mutation { 
    static fragments = { 
    images:() => Relay.QL` 
     fragment on User { 
     id, 
     }`, 
    }; 

    getMutation() { 
    return Relay.QL`mutation{ introduceImage }`; 
    } 

    getFiles() { 
    return { 
     file: this.props.file, 
    }; 
    } 

    getVariables() { 
    return { 
     imageName: this.props.file.name, 
    }; 
    } 

    getFatQuery() { 
    return Relay.QL` 
     fragment on IntroduceImagePayload { 
     User { 
      images(first: 30) { 
      edges { 
       node { 
       id, 
       } 
      } 
      } 
     }, 
     newImageEdge, 
     } 
    `; 
    } 

    getConfigs() { 
    return [{ 
     type: 'RANGE_ADD', 
     parentName: 'User', 
     parentID: this.props.images.id, 
     connectionName: 'images', 
     edgeName: 'newImageEdge', 
     rangeBehaviors: { 
     '': 'prepend', 
     }, 
    }]; 
    } 
} 

Ve son sunucu/şema üzerinde işleyicisi uygulamak.

const imageMutation = Relay.mutationWithClientMutationId({ 
    name: 'IntroduceImage', 
    inputFields: { 
    imageName: { 
     type: new GraphQL.GraphQLNonNull(GraphQL.GraphQLString), 
    }, 
    }, 
    outputFields: { 
    newImageEdge: { 
     type: ImageEdge, 
     resolve: (payload, args, options) => { 
     const file = options.rootValue.request.file; 
     //write the image to you disk 
     return uploadFile(file.buffer, filePath, filename) 
     .then(() => { 
      /* Find the offset for new edge*/ 
      return Promise.all(
      [(new myImages()).getAll(), 
       (new myImages()).getById(payload.insertId)]) 
      .spread((allImages, newImage) => { 
      const newImageStr = JSON.stringify(newImage); 
      /* If edge is in list return index */ 
      const offset = allImages.reduce((pre, ele, idx) => { 
       if (JSON.stringify(ele) === newImageStr) { 
       return idx; 
       } 
       return pre; 
      }, -1); 

      return { 
       cursor: offset !== -1 ? Relay.offsetToCursor(offset) : null, 
       node: newImage, 
      }; 
      }); 
     }); 
     }, 
    }, 
    User: { 
     type: UserType, 
     resolve:() => (new myImages()).getAll(), 
    }, 
    }, 
    mutateAndGetPayload: (input) => { 
    //break the names to array. 
    let imageName = input.imageName.substring(0, input.imageName.lastIndexOf('.')); 
    const mimeType = input.imageName.substring(input.imageName.lastIndexOf('.')); 
    //wirte the image to database 
    return (new myImages()) 
    .add(imageName) 
    .then(id => { 
    //prepare to wirte disk 
     return { 
     insertId: id, 
     imgNmae: imageName, 
     }; 
    }); 
    }, 
}); 

Rails- da bir canlı tanıtım http://fanjin.computer

+0

Lütfen cevabınıza ilgili kodu ekleyin. Yığın taşmasını önlemek için Yığın Taşması, bir cevabın "çekirdeği" için dış bağlantılara güvenmekten vazgeçirir. Sadece neyin uygun olduğunu alıntılamak ve ardından tam depoya bağlantı vermek tamamen uygun. – mech

+1

Anladım! Cevabımı güncelledim. –

4

Ben sadece onun blog Marc-Andre Giroux'nun bulgularını paylaşıyorum yoktur https://github.com/bfwg/relay-gallery sen benim repo bunları bulabilirsiniz Yukarıdaki kod, All hangi Spesifik, bu yüzden daha jenerik yapmak ve @Nick tarafından sağlanan cevabın ayrıntılarını sağlamaya çalışacağım.

  • İstemci tarafı JavaScript kodu
  • Sunucu tarafı sunucu özgü kod

İstemci tarafı JavaScript kodu

client-:

2 bölümü vardır yan kod ayrıca 2 bölümden oluşur:

  1. Relay.Mutation (UploadFileMutation)

    // The actual mutation 
    class UploadFileMutation extends Relay.Mutation { 
        getFiles() { 
        return { 
         file: this.props.file, 
        }; 
        } 
    
        // ... Rest of your mutation 
    } 
    
  2. dosyayı seçmek için UI işlemek ve Tepkisiz bileşeni (FileUploader) içeren bileşen uzanır ve mutasyon çağıran dosya yüklemek için mutasyon, yükle

    // A react component to upload a file 
    class FileUploader extends React.Component { 
        onSubmit() { 
        const name = this.refs.name.value; 
        const file = this.refs.fileInput.files.item(0); 
        Relay.Store.update(
         new UploadFileMutation({ 
         name: name, 
         file: file, 
         }) 
        ); 
        } 
    
        // ... Rest of React component, e.g., render() 
    } 
    

Sunucu tarafı Sunucu Özgü Kod yapmak

sunucu tarafında kodu da 2 kısımdan oluşur:

  1. parçalı MIME çok parçalı biçimde yüklenmiş dosya alma kolu ve GraphQL şemada tanımlanan mutasyon için geçmek için. Diğer sunucular için çözümler üretmenize yardımcı olan NodeJS ve Rails örneklerini sunuyoruz.
  2. NodeJS Hızlı sunucusu için

(express-graqphl test durumlarda elde @ Nick tarafından işaret edildiği gibi):

import multer from 'multer'; 

    var app = express(); 
    var graphqlHTTP = require('express-graphql'); 

    // Multer provides multipart form data parsing. 
    var storage = multer.memoryStorage(); 

    app.use(urlString(), multer({ storage }).single('file')); 

    // Providing the request, which contains the file MIME 
    // multipart as `rootValue` to enable it to 
    // be accessible from within Schema resolve functions. 
    app.use(urlString(), graphqlHTTP(req => { 
     return { 
     schema: YourMutationSchema, 
     rootValue: { request: req } 
     }; 
    })); 

Benzer bir şekilde, JS olmayan sunucusunun, örneğin, RubyOnRails:

def create 
     query_string = params[:query] 
     query_variables = ensure_hash(params[:variables]) || {} 

     query = GraphQL::Query.new(
     YourSchema, 
     query_string, 
     variables: query_variables, 
     # Shove the file MIME multipart into context to make it 
     # accessible by GraphQL Schema Mutation resolve methods 
     context: { file: request.params[:file] } 
    ) 
  1. Mutasyon, iletilen MIME multipart dosyasını geri alabilir
01 JavaScript GraphQL Şeması için

:

var YourMutationSchema = new GraphQLSchema({ 
     query: new GraphQLObjectType({ 
     // ... QueryType Schema 
     }), 
     mutation: new GraphQLObjectType({ 
     name: 'MutationRoot', 
     fields: { 
      uploadFile: { 
      type: UploadedFileType, 
      resolve(rootValue) { 
       // Access file MIME multipart using 
       const _file = rootValue.request.file; 

       // ... Do something with file 
      } 
      } 
     } 
     }) 
    }); 

Raylar için GraphQL Şeması:

AddFileMutation = GraphQL::Relay::Mutation.define do 
     name "AddFile" 
     input_field :name, !types.String 

     # ... Add your standard mutation schema stuff here 

     resolve -> (args, ctx) { 
     # Retrieve the file MIME multipart 
     file = ctx[:file] 
     raise StandardError.new("Expected a file") unless file 

     # ... Do something with file 
     } 
    end 
+0

harika cevap! :) – bryce

1

Röle Modern ile, diğer cevaplara eklemek için dosyaları göndermesi gerektiğini nasıl küçük bir değişiklik oldu müşteri.

UploadFileMutation.js

// @flow 

import { commitMutation, graphql } from 'react-relay'; 

import type { Environment } from 'react-relay'; 
import type { UploadFileInput, UploadFileMutationResponse } from './__generated__/uploadFileMutation.graphql'; 

const mutation = graphql` 
    mutation UploadFileMutation($input: UploadFileInput!) { 
    UploadFile(input: $input) { 
     error 
     file { 
     url 
     } 
    } 
    } 
`; 

const getOptimisticResponse = (file: File | Blob) => ({ 
    UploadFile: { 
    error: null, 
    file: { 
     url: file.uri, 
    }, 
    }, 
}); 

function commit(
    environment: Environment, 
    { fileName }: UploadFileInput, 
    onCompleted: (data: UploadFileMutationResponse) => void, 
    onError:() => void, 
    uploadables, 
) { 
    return commitMutation(environment, { 
    mutation, 
    variables: { 
     input: { fileName }, 
    }, 
    optimisticResponse: getOptimisticResponse(uploadables.fileToUpload), 
    onCompleted, 
    onError, 
    uploadables, 
    }); 
} 

export default { commit }; 

Kullanım bileşeni üzerinde

:

Bunun yerine mutasyon bir getFiles sahip ve yapıcı dosyaları geçme, aşağıdaki gibi bir şey kullanabilirsiniz
const uploadables = { 
    fileToUpload: file, // file is the value of an input field for example 
}; 

UploadFileMutation.commit(
    this.props.relay.environment, 
    { fileName }, 
    onCompleted, 
    onError, 
    uploadables 
); 

The uploadables config seçeneği gizlidir, çünkü dokümanlar üzerinde hiç bir şey yoktur, ancak şu adreste bulunabilir: https://github.com/facebook/relay/blob/c4430643002ec409d815366b0721ba88ed3a855a/packages/relay-runtime/mutations/commitRelayModernMutation.js#L32